mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-10 14:44:12 +00:00
wip: move children onto scope
This commit is contained in:
parent
d1b294fff0
commit
f438bbcfd2
6 changed files with 85 additions and 19 deletions
|
@ -37,7 +37,7 @@ once_cell = "1.8.0"
|
|||
|
||||
indexmap = "1.7.0"
|
||||
|
||||
# # Serialize the Edits for use in Webview/Liveview instances
|
||||
# Serialize the Edits for use in Webview/Liveview instances
|
||||
serde = { version = "1", features = ["derive"], optional = true }
|
||||
|
||||
serde_repr = { version = "0.1.7", optional = true }
|
||||
|
|
|
@ -66,15 +66,15 @@ pub(crate) mod innerlude {
|
|||
|
||||
pub use crate::innerlude::{
|
||||
Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, MountType, Mutations,
|
||||
NodeFactory, Properties, SchedulerMsg, ScopeId, SuspendedContext, TaskHandle, TestDom,
|
||||
ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC,
|
||||
NodeFactory, Properties, SchedulerMsg, ScopeChildren, ScopeId, SuspendedContext, TaskHandle,
|
||||
TestDom, ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC,
|
||||
};
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::component::{fc_to_builder, Fragment, Properties, Scope};
|
||||
pub use crate::context::Context;
|
||||
pub use crate::hooks::*;
|
||||
pub use crate::innerlude::{DioxusElement, Element, LazyNodes, NodeFactory, FC};
|
||||
pub use crate::innerlude::{DioxusElement, Element, LazyNodes, NodeFactory, ScopeChildren, FC};
|
||||
pub use crate::nodes::VNode;
|
||||
pub use crate::VirtualDom;
|
||||
}
|
||||
|
|
|
@ -726,3 +726,65 @@ impl IntoVNode<'_> for Arguments<'_> {
|
|||
cx.text(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the children elements passed into the component
|
||||
///
|
||||
/// This enables patterns where a component is passed children from its parent.
|
||||
///
|
||||
/// ## Details
|
||||
///
|
||||
/// Unlike React, Dioxus allows *only* lists of children to be passed from parent to child - not arbitrary functions
|
||||
/// or classes. If you want to generate nodes instead of accepting them as a list, consider declaring a closure
|
||||
/// on the props that takes Context.
|
||||
///
|
||||
/// If a parent passes children into a component, the child will always re-render when the parent re-renders. In other
|
||||
/// words, a component cannot be automatically memoized if it borrows nodes from its parent, even if the component's
|
||||
/// props are valid for the static lifetime.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// const App: FC<()> = |(cx, props)|{
|
||||
/// cx.render(rsx!{
|
||||
/// CustomCard {
|
||||
/// h1 {}
|
||||
/// p {}
|
||||
/// }
|
||||
/// })
|
||||
/// }
|
||||
///
|
||||
/// const CustomCard: FC<()> = |(cx, props)|{
|
||||
/// cx.render(rsx!{
|
||||
/// div {
|
||||
/// h1 {"Title card"}
|
||||
/// {props.children}
|
||||
/// }
|
||||
/// })
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ## Notes:
|
||||
///
|
||||
/// This method returns a "ScopeChildren" object. This object is copy-able and preserve the correct lifetime.
|
||||
pub struct ScopeChildren<'a> {
|
||||
root: Option<VNode<'a>>,
|
||||
}
|
||||
|
||||
impl IntoIterator for &ScopeChildren<'_> {
|
||||
type Item = Self;
|
||||
|
||||
type IntoIter = std::iter::Once<Self>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoVNode<'a> for &ScopeChildren<'a> {
|
||||
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
||||
match &self.root {
|
||||
Some(n) => n.decouple(),
|
||||
None => cx.fragment_from_iter(None as Option<VNode>),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -340,8 +340,6 @@ impl ScopeInner {
|
|||
let render: &dyn for<'b> Fn(&'b ScopeInner) -> Element<'b> = unsafe { &*self.caller };
|
||||
|
||||
// Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders.
|
||||
//
|
||||
// todo!()
|
||||
if let Some(builder) = render(self) {
|
||||
let new_head = builder.into_vnode(NodeFactory {
|
||||
bump: &self.frames.wip_frame().bump,
|
||||
|
|
|
@ -64,10 +64,10 @@ fn create() {
|
|||
"Hello, world!"
|
||||
div {
|
||||
div {
|
||||
Fragment {
|
||||
"hello"
|
||||
"world"
|
||||
}
|
||||
// Fragment {
|
||||
// "hello"
|
||||
// "world"
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,20 +208,26 @@ fn create_simple() {
|
|||
#[test]
|
||||
fn create_components() {
|
||||
static App: FC<()> = |(cx, props)| {
|
||||
cx.render(rsx! {
|
||||
Child { "abc1" }
|
||||
Child { "abc2" }
|
||||
Child { "abc3" }
|
||||
})
|
||||
todo!()
|
||||
// cx.render(rsx! {
|
||||
// Child { "abc1" }
|
||||
// Child { "abc2" }
|
||||
// Child { "abc3" }
|
||||
// })
|
||||
};
|
||||
|
||||
static Child: FC<()> = |(cx, props)| {
|
||||
#[derive(Props)]
|
||||
struct ChildProps<'a> {
|
||||
children: ScopeChildren<'a>,
|
||||
}
|
||||
|
||||
fn Child<'a>((cx, props): Scope<'a, ChildProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
h1 {}
|
||||
div { {cx.children()} }
|
||||
div { {&props.children} }
|
||||
p {}
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
let mut dom = new_dom(App, ());
|
||||
let mutations = dom.rebuild();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(unused, non_upper_case_globals)]
|
||||
|
||||
use dioxus::{prelude::*, DomEdit, TestDom};
|
||||
use dioxus::{prelude::*, DomEdit, Mutations, TestDom};
|
||||
use dioxus_core as dioxus;
|
||||
use dioxus_core_macro::*;
|
||||
use dioxus_html as dioxus_elements;
|
||||
|
|
Loading…
Reference in a new issue