diff --git a/packages/core-macro/src/rsx/component.rs b/packages/core-macro/src/rsx/component.rs index 35963b8b5..c65fc9ee1 100644 --- a/packages/core-macro/src/rsx/component.rs +++ b/packages/core-macro/src/rsx/component.rs @@ -161,12 +161,22 @@ impl ToTokens for Component { None => { let mut toks = quote! { fc_to_builder(#name) }; for field in &self.body { - if field.name == "key" { - has_key = Some(field); - } else { - toks.append_all(quote! {#field}) + match field.name.to_string().as_str() { + "key" => { + // + has_key = Some(field); + } + _ => toks.append_all(quote! {#field}), } } + + if !self.children.is_empty() { + let childs = &self.children; + toks.append_all(quote! { + .children(ScopeChildren::new(__cx.fragment_from_iter([ #( #childs ),* ]))) + }); + } + toks.append_all(quote! { .build() }); @@ -182,17 +192,13 @@ impl ToTokens for Component { None => quote! { None }, }; - let childs = &self.children; - let children = quote! { - [ #( #childs ),* ] - }; + // #children tokens.append_all(quote! { __cx.component( #name, #builder, #key_token, - #children ) }) } diff --git a/packages/core/examples/syntax2.rs b/packages/core/examples/syntax2.rs index 4cbd22ab5..54c0bedaa 100644 --- a/packages/core/examples/syntax2.rs +++ b/packages/core/examples/syntax2.rs @@ -230,15 +230,10 @@ fn Child2<'a>((cx, props): Scope<'a, Child2Props>) -> Element<'a> { }) .unwrap(); - let b = cx.bump(); - let node: &'a VNode<'a> = b.alloc(node); - - let children = Children { pthru: node }; - cx.render(rsx! { div { ChildrenComp { - children: children + div {} } } }) @@ -246,46 +241,14 @@ fn Child2<'a>((cx, props): Scope<'a, Child2Props>) -> Element<'a> { #[derive(Props)] struct ChildrenTest<'a> { - children: Children<'a>, -} - -struct Children<'a> { - pthru: &'a VNode<'a>, -} - -impl<'a> Clone for Children<'a> { - fn clone(&self) -> Self { - Self { pthru: self.pthru } - } -} -impl<'a> Copy for Children<'a> {} - -impl<'a> IntoVNode<'a> for Children<'a> { - fn into_vnode(self, _: NodeFactory<'a>) -> VNode<'a> { - match self.pthru { - VNode::Text(f) => VNode::Text(*f), - VNode::Element(e) => VNode::Element(*e), - VNode::Component(c) => VNode::Component(*c), - VNode::Suspended(s) => VNode::Suspended(*s), - VNode::Anchor(a) => VNode::Anchor(a), - VNode::Fragment(f) => VNode::Fragment(VFragment { - children: f.children, - is_static: f.is_static, - key: f.key, - }), - } - } + children: ScopeChildren<'a>, } fn ChildrenComp<'a>((cx, props): Scope<'a, ChildrenTest<'a>>) -> Element<'a> { cx.render(rsx! { div { div { - - // if the node's id is already assigned, then it's being passed in as a child - // in these instances, we don't worry about re-checking the node? - - {Some(props.children)} + {&props.children} } } }) diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index 69ca60ede..728a1f4cf 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -187,11 +187,7 @@ impl Debug for VNode<'_> { VNode::Fragment(frag) => write!(s, "VFragment {{ children: {:?} }}", frag.children), VNode::Suspended { .. } => write!(s, "VSuspended"), - VNode::Component(comp) => write!( - s, - "VComponent {{ fc: {:?}, children: {:?} }}", - comp.user_fc, comp.children - ), + VNode::Component(comp) => write!(s, "VComponent {{ fc: {:?}}}", comp.user_fc), } } } @@ -331,8 +327,6 @@ pub struct VComponent<'src> { pub(crate) caller: &'src dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>, - pub(crate) children: &'src [VNode<'src>], - pub(crate) comparator: Option<&'src dyn Fn(&VComponent) -> bool>, pub(crate) drop_props: RefCell>>, @@ -483,20 +477,16 @@ impl<'a> NodeFactory<'a> { } } - pub fn component( + pub fn component

( &self, component: fn(Scope<'a, P>) -> Element<'a>, props: P, key: Option, - children: V, ) -> VNode<'a> where P: Properties + 'a, - V: AsRef<[VNode<'a>]> + 'a, { let bump = self.bump(); - let children: &'a V = bump.alloc(children); - let children = children.as_ref(); let props = bump.alloc(props); let raw_props = props as *mut P as *mut (); let user_fc = component as *const (); @@ -518,7 +508,7 @@ impl<'a> NodeFactory<'a> { // It's only okay to memoize if there are no children and the props can be memoized // Implementing memoize is unsafe and done automatically with the props trait - matches!((props_memoized, children.is_empty()), (true, true)) + props_memoized } else { false } @@ -549,8 +539,6 @@ impl<'a> NodeFactory<'a> { RefCell::new(Some(drop_props)) }; - let is_static = children.is_empty() && P::IS_STATIC && key.is_none(); - let key = key.map(|f| self.raw_text(f).0); let caller: &'a mut dyn for<'b> Fn(&'b ScopeInner) -> Element<'b> = @@ -565,17 +553,14 @@ impl<'a> NodeFactory<'a> { unsafe { std::mem::transmute(res) } }); - let can_memoize = children.is_empty() && P::IS_STATIC; - VNode::Component(bump.alloc(VComponent { user_fc, comparator, raw_props, - children, caller, - is_static, + is_static: P::IS_STATIC, key, - can_memoize, + can_memoize: P::IS_STATIC, drop_props, associated_scope: Cell::new(None), })) @@ -770,6 +755,18 @@ pub struct ScopeChildren<'a> { root: Option>, } +impl Default for ScopeChildren<'_> { + fn default() -> Self { + Self { root: None } + } +} + +impl<'a> ScopeChildren<'a> { + pub fn new(root: VNode<'a>) -> Self { + Self { root: Some(root) } + } +} + impl IntoIterator for &ScopeChildren<'_> { type Item = Self; diff --git a/packages/core/tests/create_dom.rs b/packages/core/tests/create_dom.rs index f40343362..875db7a75 100644 --- a/packages/core/tests/create_dom.rs +++ b/packages/core/tests/create_dom.rs @@ -208,12 +208,11 @@ fn create_simple() { #[test] fn create_components() { static App: FC<()> = |(cx, props)| { - todo!() - // cx.render(rsx! { - // Child { "abc1" } - // Child { "abc2" } - // Child { "abc3" } - // }) + cx.render(rsx! { + Child { "abc1" } + Child { "abc2" } + Child { "abc3" } + }) }; #[derive(Props)]