wip: remove cx.children. start to move towards a "children" field

This commit is contained in:
Jonathan Kelley committed 2021-11-01 02:22:08 -04:00
1 parent 6b2645fd80
commit 7b97e009ec
14 files changed
+114 -276

No files matched your search

+8 -61
View File
@@ -233,65 +233,12 @@ fn Child2<'a>((cx, props): Scope<'a, Child2Props>) -> Element<'a> {
let b = cx.bump(); let b = cx.bump();
let node: &'a VNode<'a> = b.alloc(node); let node: &'a VNode<'a> = b.alloc(node);
let children = ChildList { pthru: node }; let children = Children { pthru: node };
// let c = VComponent {
// key: todo!(),
// associated_scope: todo!(),
// is_static: todo!(),
// user_fc: todo!(),
// caller: todo!(),
// children: todo!(),
// comparator: todo!(),
// drop_props: todo!(),
// can_memoize: todo!(),
// raw_props: todo!(),
// };
// Vcomp
// - borrowed
// - memoized
// cx.render({
// NodeFactory::annotate_lazy(move |__cx: NodeFactory| -> VNode {
// use dioxus_elements::{GlobalAttributes, SvgAttributes};
// __cx.element(
// dioxus_elements::div,
// [],
// [],
// [
// __cx.component(ChildrenMemo, (), None, []),
// __cx.component(
// ChildrenComp,
// //
// ChildrenTest { node: children },
// None,
// [],
// ),
// // {
// // let _props: &_ = __cx.bump().alloc(ChildrenTest { node: children });
// // __cx.component_v2_borrowed(
// // //
// // move |c| ChildrenComp((c, _props)),
// // ChildrenComp,
// // _props,
// // )
// // },
// // {
// // let _props: &_ = __cx.bump().alloc(());
// // __cx.component_v2_borrowed(move |c| ChildrenMemo((c, _props)))
// // },
// ],
// None,
// )
// })
// })
cx.render(rsx! { cx.render(rsx! {
div { div {
ChildrenComp { ChildrenComp {
..ChildrenTest { children: children
node: children,
}
} }
} }
}) })
@@ -299,21 +246,21 @@ fn Child2<'a>((cx, props): Scope<'a, Child2Props>) -> Element<'a> {
#[derive(Props)] #[derive(Props)]
struct ChildrenTest<'a> { struct ChildrenTest<'a> {
node: ChildList<'a>, children: Children<'a>,
} }
struct ChildList<'a> { struct Children<'a> {
pthru: &'a VNode<'a>, pthru: &'a VNode<'a>,
} }
impl<'a> Clone for ChildList<'a> { impl<'a> Clone for Children<'a> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { pthru: self.pthru } Self { pthru: self.pthru }
} }
} }
impl<'a> Copy for ChildList<'a> {} impl<'a> Copy for Children<'a> {}
impl<'a> IntoVNode<'a> for ChildList<'a> { impl<'a> IntoVNode<'a> for Children<'a> {
fn into_vnode(self, _: NodeFactory<'a>) -> VNode<'a> { fn into_vnode(self, _: NodeFactory<'a>) -> VNode<'a> {
match self.pthru { match self.pthru {
VNode::Text(f) => VNode::Text(*f), VNode::Text(f) => VNode::Text(*f),
@@ -338,7 +285,7 @@ fn ChildrenComp<'a>((cx, props): Scope<'a, ChildrenTest<'a>>) -> Element<'a> {
// if the node's id is already assigned, then it's being passed in as a child // 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? // in these instances, we don't worry about re-checking the node?
{Some(props.node)} {Some(props.children)}
} }
} }
}) })
+3 -3
View File
@@ -2,8 +2,8 @@ use std::time::Duration;
use dioxus_core::prelude::*; use dioxus_core::prelude::*;
#[async_std::main] // #[async_std::main]
async fn main() { fn main() {
static App: FC<()> = static App: FC<()> =
|(cx, props)| cx.render(Some(Box::new(move |f| f.text(format_args!("hello"))))); |(cx, props)| cx.render(Some(Box::new(move |f| f.text(format_args!("hello")))));
@@ -11,7 +11,7 @@ async fn main() {
dom.rebuild(); dom.rebuild();
let deadline = async_std::task::sleep(Duration::from_millis(50)); // let deadline = async_std::task::sleep(Duration::from_millis(50));
// let _fut = dom.run_with_deadline(|| deadline.); // let _fut = dom.run_with_deadline(|| deadline.);
} }
+1 -1
View File
@@ -138,6 +138,6 @@ impl EmptyBuilder {
/// This utility function launches the builder method so rsx! and html! macros can use the typed-builder pattern /// This utility function launches the builder method so rsx! and html! macros can use the typed-builder pattern
/// to initialize a component's props. /// to initialize a component's props.
pub fn fc_to_builder<T: Properties>(_: FC<T>) -> T::Builder { pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Scope<'a, T>) -> Element<'a>) -> T::Builder {
T::builder() T::builder()
} }
+1 -62
View File
@@ -54,49 +54,6 @@ impl<'a> Deref for Context<'a> {
} }
impl<'src> Context<'src> { impl<'src> Context<'src> {
/// 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"}
/// {cx.children()}
/// }
/// })
/// }
/// ```
///
/// ## Notes:
///
/// This method returns a "ScopeChildren" object. This object is copy-able and preserve the correct lifetime.
pub fn children(&self) -> ScopeChildren<'src> {
self.scope.child_nodes()
}
/// Create a subscription that schedules a future render for the reference component /// Create a subscription that schedules a future render for the reference component
/// ///
/// ## Notice: you should prefer using prepare_update and get_scope_id /// ## Notice: you should prefer using prepare_update and get_scope_id
@@ -147,28 +104,10 @@ impl<'src> Context<'src> {
pub fn render( pub fn render(
self, self,
lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'src>) -> VNode<'src> + '_>>, lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'src>) -> VNode<'src> + '_>>,
// lazy_nodes: Option<Box<dyn FnOnce(NodeFactory) -> VNode + '_>>,
// lazy_nodes: Box<dyn FnOnce(NodeFactory<'src>) -> VNode<'src> + '_>,
) -> Option<VNode<'src>> { ) -> Option<VNode<'src>> {
// pub fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>(
// self,
// lazy_nodes: LazyNodes<'src, F>,
// ) -> Option<VNode<'src>> {
let bump = &self.scope.frames.wip_frame().bump; let bump = &self.scope.frames.wip_frame().bump;
// Some(lazy_nodes.into_vnode(NodeFactory { bump }))
let factory = NodeFactory { bump }; let factory = NodeFactory { bump };
// let vnode = lazy_nodes(factory); lazy_nodes.map(|f| f(factory))
match lazy_nodes {
Some(f) => Some(f(factory)),
None => None,
}
// match lazy_nodes {
// None => todo!(),
// }
// Some(lazy_nodes)
} }
/// `submit_task` will submit the future to be polled. /// `submit_task` will submit the future to be polled.
+1 -2
View File
@@ -348,7 +348,6 @@ impl<'bump> DiffMachine<'bump> {
Some(parent_idx), Some(parent_idx),
parent_scope.height + 1, parent_scope.height + 1,
parent_scope.subtree(), parent_scope.subtree(),
ScopeChildren(vcomponent.children),
shared, shared,
) )
}); });
@@ -555,7 +554,7 @@ impl<'bump> DiffMachine<'bump> {
// make sure the component's caller function is up to date // make sure the component's caller function is up to date
let scope = self.vdom.get_scope_mut(scope_addr).unwrap(); let scope = self.vdom.get_scope_mut(scope_addr).unwrap();
scope.update_scope_dependencies(new.caller, ScopeChildren(new.children)); scope.update_scope_dependencies(new.caller);
// React doesn't automatically memoize, but we do. // React doesn't automatically memoize, but we do.
let props_are_the_same = old.comparator.unwrap(); let props_are_the_same = old.comparator.unwrap();
+23 -79
View File
@@ -638,47 +638,6 @@ pub trait IntoVNode<'a> {
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a>; fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a>;
} }
/// Child nodes of the parent component.
///
/// # Example
///
/// ```rust
/// let children = cx.children();
/// let first_node = &children[0];
/// rsx!{
/// h1 { {first_node} }
/// p { {&children[1..]} }
/// }
/// ```
///
pub struct ScopeChildren<'a>(pub &'a [VNode<'a>]);
impl Copy for ScopeChildren<'_> {}
impl<'a> Clone for ScopeChildren<'a> {
fn clone(&self) -> Self {
ScopeChildren(self.0)
}
}
impl ScopeChildren<'_> {
// dangerous method - used to fix the associated lifetime
pub(crate) unsafe fn extend_lifetime(self) -> ScopeChildren<'static> {
std::mem::transmute(self)
}
// dangerous method - used to fix the associated lifetime
pub(crate) unsafe fn shorten_lifetime<'a>(self) -> ScopeChildren<'a> {
std::mem::transmute(self)
}
}
// impl IntoVNodeList for ScopeChildren<'_> {
// fn into_vnode_list<'a>(self, _: NodeFactory<'a>) -> &'a [VNode<'a>] {
// self.0
// }
// }
// For the case where a rendered VNode is passed into the rsx! macro through curly braces // For the case where a rendered VNode is passed into the rsx! macro through curly braces
impl<'a> IntoIterator for VNode<'a> { impl<'a> IntoIterator for VNode<'a> {
type Item = VNode<'a>; type Item = VNode<'a>;
@@ -690,34 +649,31 @@ impl<'a> IntoIterator for VNode<'a> {
// TODO: do we even need this? It almost seems better not to // TODO: do we even need this? It almost seems better not to
// // For the case where a rendered VNode is passed into the rsx! macro through curly braces // // For the case where a rendered VNode is passed into the rsx! macro through curly braces
// impl IntoVNode for VNode<'_> { impl<'a> IntoVNode<'a> for VNode<'a> {
// fn into_vnode<'a>(self, _: NodeFactory<'a>) -> VNode<'a> { fn into_vnode(self, _: NodeFactory<'a>) -> VNode<'a> {
// self self
// } }
// } }
// Conveniently, we also support "null" (nothing) passed in // Conveniently, we also support "null" (nothing) passed in
// impl IntoVNode for () { impl IntoVNode<'_> for () {
// fn into_vnode(self, cx: NodeFactory) -> VNode { fn into_vnode(self, cx: NodeFactory) -> VNode {
// cx.fragment_from_iter(None as Option<VNode>) cx.fragment_from_iter(None as Option<VNode>)
// } }
// } }
// // Conveniently, we also support "None" // Conveniently, we also support "None"
// impl IntoVNode for Option<()> { impl IntoVNode<'_> for Option<()> {
// fn into_vnode(self, cx: NodeFactory) -> VNode { fn into_vnode(self, cx: NodeFactory) -> VNode {
// cx.fragment_from_iter(None as Option<VNode>) cx.fragment_from_iter(None as Option<VNode>)
// } }
// } }
// impl IntoVNode for Option<VNode<'_>> { impl<'a> IntoVNode<'a> for Option<VNode<'a>> {
// fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> { fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
// match self { self.unwrap_or_else(|| cx.fragment_from_iter(None as Option<VNode>))
// Some(n) => n, }
// None => cx.fragment_from_iter(None as Option<VNode>), }
// }
// }
// }
pub fn annotate_lazy<'a, 'b, F>(f: F) -> Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>> pub fn annotate_lazy<'a, 'b, F>(f: F) -> Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>>
where where
@@ -729,11 +685,7 @@ where
impl<'a> IntoVNode<'a> for Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>> { impl<'a> IntoVNode<'a> for Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>> {
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> { fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
match self { match self {
Some(n) => { Some(lazy) => lazy(cx),
//
// n.into_vnode(cx)
n(cx)
}
None => VNode::Fragment(VFragment { None => VNode::Fragment(VFragment {
children: &[], children: &[],
is_static: false, is_static: false,
@@ -749,20 +701,12 @@ impl<'a> IntoVNode<'a> for Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_> {
} }
} }
// impl<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> IntoVNode<'a> for Option<LazyNodes<'a, F>> {
// fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
// match self {
// Some(n) => n.into_vnode(cx),
// None => cx.fragment_from_iter(None as Option<VNode>),
// }
// }
// }
impl IntoVNode<'_> for &'static str { impl IntoVNode<'_> for &'static str {
fn into_vnode(self, cx: NodeFactory) -> VNode { fn into_vnode(self, cx: NodeFactory) -> VNode {
cx.static_text(self) cx.static_text(self)
} }
} }
impl IntoVNode<'_> for Arguments<'_> { impl IntoVNode<'_> for Arguments<'_> {
fn into_vnode(self, cx: NodeFactory) -> VNode { fn into_vnode(self, cx: NodeFactory) -> VNode {
cx.text(self) cx.text(self)
-13
View File
@@ -29,7 +29,6 @@ pub struct ScopeInner {
// Nodes // Nodes
pub(crate) frames: ActiveFrame, pub(crate) frames: ActiveFrame,
pub(crate) caller: *const dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>, pub(crate) caller: *const dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>,
pub(crate) child_nodes: ScopeChildren<'static>,
/* /*
we care about: we care about:
@@ -181,11 +180,8 @@ impl ScopeInner {
parent_idx: Option<ScopeId>, parent_idx: Option<ScopeId>,
height: u32, height: u32,
subtree: u32, subtree: u32,
child_nodes: ScopeChildren,
shared: EventChannel, shared: EventChannel,
) -> Self { ) -> Self {
let child_nodes = unsafe { child_nodes.extend_lifetime() };
let schedule_any_update = shared.schedule_any_immediate.clone(); let schedule_any_update = shared.schedule_any_immediate.clone();
let memoized_updater = Rc::new(move || schedule_any_update(our_arena_idx)); let memoized_updater = Rc::new(move || schedule_any_update(our_arena_idx));
@@ -198,7 +194,6 @@ impl ScopeInner {
Self { Self {
memoized_updater, memoized_updater,
shared, shared,
child_nodes,
caller, caller,
parent_idx, parent_idx,
our_arena_idx, our_arena_idx,
@@ -218,18 +213,10 @@ impl ScopeInner {
pub(crate) fn update_scope_dependencies<'creator_node>( pub(crate) fn update_scope_dependencies<'creator_node>(
&mut self, &mut self,
caller: &'creator_node dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>, caller: &'creator_node dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>,
child_nodes: ScopeChildren,
) { ) {
log::debug!("Updating scope dependencies {:?}", self.our_arena_idx); log::debug!("Updating scope dependencies {:?}", self.our_arena_idx);
let caller = caller as *const _; let caller = caller as *const _;
self.caller = unsafe { std::mem::transmute(caller) }; self.caller = unsafe { std::mem::transmute(caller) };
let child_nodes = unsafe { child_nodes.extend_lifetime() };
self.child_nodes = child_nodes;
}
pub(crate) fn child_nodes(&self) -> ScopeChildren {
unsafe { self.child_nodes.shorten_lifetime() }
} }
/// This method cleans up any references to data held within our hook list. This prevents mutable aliasing from /// This method cleans up any references to data held within our hook list. This prevents mutable aliasing from
+14 -7
View File
@@ -21,7 +21,10 @@ impl TestDom {
NodeFactory::new(&self.bump) NodeFactory::new(&self.bump)
} }
pub fn render_direct<'a>(&'a self, lazy_nodes: Element<'a>) -> VNode<'a> pub fn render_direct<'a>(
&'a self,
lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
) -> VNode<'a>
// where // where
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>, // F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
{ {
@@ -29,7 +32,10 @@ impl TestDom {
// lazy_nodes.into_vnode(NodeFactory::new(&self.bump)) // lazy_nodes.into_vnode(NodeFactory::new(&self.bump))
} }
pub fn render<'a>(&'a self, lazy_nodes: Element<'a>) -> &'a VNode<'a> pub fn render<'a>(
&'a self,
lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
) -> &'a VNode<'a>
// where // where
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>, // F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
{ {
@@ -45,7 +51,10 @@ impl TestDom {
machine.mutations machine.mutations
} }
pub fn create<'a>(&'a self, left: Element<'a>) -> Mutations<'a> pub fn create<'a>(
&'a self,
left: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
) -> Mutations<'a>
// pub fn create<'a, F1>(&'a self, left: LazyNodes<'a, F1>) -> Mutations<'a> // pub fn create<'a, F1>(&'a self, left: LazyNodes<'a, F1>) -> Mutations<'a>
// where // where
// F1: FnOnce(NodeFactory<'a>) -> VNode<'a>, // F1: FnOnce(NodeFactory<'a>) -> VNode<'a>,
@@ -63,10 +72,8 @@ impl TestDom {
pub fn lazy_diff<'a>( pub fn lazy_diff<'a>(
&'a self, &'a self,
left: Element<'a>, left: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
right: Element<'a>, right: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
// left: LazyNodes<'a, F1>,
// right: LazyNodes<'a, F2>,
) -> (Mutations<'a>, Mutations<'a>) ) -> (Mutations<'a>, Mutations<'a>)
// where // where
// F1: FnOnce(NodeFactory<'a>) -> VNode<'a>, // F1: FnOnce(NodeFactory<'a>) -> VNode<'a>,
+1 -2
View File
@@ -158,7 +158,6 @@ impl VirtualDom {
None, None,
0, 0,
0, 0,
ScopeChildren(&[]),
scheduler.pool.channel.clone(), scheduler.pool.channel.clone(),
) )
}); });
@@ -226,7 +225,7 @@ impl VirtualDom {
std::mem::transmute(root((Context { scope }, props))) std::mem::transmute(root((Context { scope }, props)))
}); });
root_scope.update_scope_dependencies(&root_caller, ScopeChildren(&[])); root_scope.update_scope_dependencies(&root_caller);
drop(root_props); drop(root_props);
+30 -16
View File
@@ -22,13 +22,13 @@ fn new_dom<P: 'static + Send>(app: FC<P>, props: P) -> VirtualDom {
#[test] #[test]
fn test_original_diff() { fn test_original_diff() {
static APP: FC<()> = |(cx, props)| { static APP: FC<()> = |(cx, props)| {
rsx! { cx.render(rsx! {
div { div {
div { div {
"Hello, world!" "Hello, world!"
} }
} }
} })
}; };
let mut dom = new_dom(APP, ()); let mut dom = new_dom(APP, ());
@@ -58,7 +58,7 @@ fn test_original_diff() {
#[test] #[test]
fn create() { fn create() {
static APP: FC<()> = |(cx, props)| { static APP: FC<()> = |(cx, props)| {
rsx! { cx.render(rsx! {
div { div {
div { div {
"Hello, world!" "Hello, world!"
@@ -72,7 +72,7 @@ fn create() {
} }
} }
} }
} })
}; };
let mut dom = new_dom(APP, ()); let mut dom = new_dom(APP, ());
@@ -121,11 +121,11 @@ fn create() {
#[test] #[test]
fn create_list() { fn create_list() {
static APP: FC<()> = |(cx, props)| { static APP: FC<()> = |(cx, props)| {
rsx! { cx.render(rsx! {
{(0..3).map(|f| rsx!{ div { {(0..3).map(|f| rsx!{ div {
"hello" "hello"
}})} }})}
} })
}; };
let mut dom = new_dom(APP, ()); let mut dom = new_dom(APP, ());
@@ -170,12 +170,12 @@ fn create_list() {
#[test] #[test]
fn create_simple() { fn create_simple() {
static APP: FC<()> = |(cx, props)| { static APP: FC<()> = |(cx, props)| {
rsx! { cx.render(rsx! {
div {} div {}
div {} div {}
div {} div {}
div {} div {}
} })
}; };
let mut dom = new_dom(APP, ()); let mut dom = new_dom(APP, ());
@@ -208,19 +208,19 @@ fn create_simple() {
#[test] #[test]
fn create_components() { fn create_components() {
static App: FC<()> = |(cx, props)| { static App: FC<()> = |(cx, props)| {
rsx! { cx.render(rsx! {
Child { "abc1" } Child { "abc1" }
Child { "abc2" } Child { "abc2" }
Child { "abc3" } Child { "abc3" }
} })
}; };
static Child: FC<()> = |(cx, props)| { static Child: FC<()> = |(cx, props)| {
rsx! { cx.render(rsx! {
h1 {} h1 {}
div { {cx.children()} } div { {cx.children()} }
p {} p {}
} })
}; };
let mut dom = new_dom(App, ()); let mut dom = new_dom(App, ());
@@ -269,10 +269,10 @@ fn create_components() {
#[test] #[test]
fn anchors() { fn anchors() {
static App: FC<()> = |(cx, props)| { static App: FC<()> = |(cx, props)| {
rsx! { cx.render(rsx! {
{true.then(|| rsx!{ div { "hello" } })} {true.then(|| rsx!{ div { "hello" } })}
{false.then(|| rsx!{ div { "goodbye" } })} {false.then(|| rsx!{ div { "goodbye" } })}
} })
}; };
let mut dom = new_dom(App, ()); let mut dom = new_dom(App, ());
@@ -303,9 +303,23 @@ fn suspended() {
|| async { || async {
// //
}, },
|cx, p| rsx! { "hi "}, |cx, p| todo!(),
// |cx, p| rsx! { "hi "},
); );
rsx! { {val} }
// let prom = use_task(fetch());
// Value {
// a: value.await,
// b: value.await,
// f: a.await
// div {
// div {
// hidden: should_hide.await,
// }
// }
// }
cx.render(rsx! { {val} })
}; };
let mut dom = new_dom(App, ()); let mut dom = new_dom(App, ());
+15 -14
View File
@@ -433,11 +433,11 @@ fn keyed_diffing_order() {
let dom = new_dom(); let dom = new_dom();
let left = rsx!( let left = rsx!(
{(0..5).map(|f| {rsx! { div { key: "{f}" }}})} // {(0..5).map(|f| {rsx! { div { key: "{f}" }}})}
p {"e"} p {"e"}
); );
let right = rsx!( let right = rsx!(
{(0..2).map(|f| {rsx! { div { key: "{f}" }}})} {(0..2).map(|f| rsx! { div { key: "{f}" }})}
p {"e"} p {"e"}
); );
@@ -807,16 +807,17 @@ fn controlled_keyed_diffing_out_of_order_max_test() {
fn suspense() { fn suspense() {
let dom = new_dom(); let dom = new_dom();
let edits = dom.create(Some(LazyNodes::new(|f| { todo!()
use std::cell::{Cell, RefCell}; // let edits = dom.create(Some(LazyNodes::new(|f| {
VNode::Suspended(f.bump().alloc(VSuspended { // use std::cell::{Cell, RefCell};
task_id: 0, // VNode::Suspended(f.bump().alloc(VSuspended {
callback: RefCell::new(None), // task_id: 0,
dom_id: Cell::new(None), // callback: RefCell::new(None),
})) // dom_id: Cell::new(None),
}))); // }))
assert_eq!( // })));
edits.edits, // assert_eq!(
[CreatePlaceholder { root: 0 }, AppendChildren { many: 1 }] // edits.edits,
); // [CreatePlaceholder { root: 0 }, AppendChildren { many: 1 }]
// );
} }
+1 -1
View File
@@ -22,7 +22,7 @@ fn manual_diffing() {
static App: FC<AppProps> = |(cx, props)| { static App: FC<AppProps> = |(cx, props)| {
let val = props.value.lock().unwrap(); let val = props.value.lock().unwrap();
rsx! { div { "{val}" } } cx.render(rsx! { div { "{val}" } })
}; };
let value = Arc::new(Mutex::new("Hello")); let value = Arc::new(Mutex::new("Hello"));
+2 -2
View File
@@ -15,12 +15,12 @@ fn shared_state_test() {
static App: FC<()> = |(cx, props)| { static App: FC<()> = |(cx, props)| {
cx.provide_state(MySharedState("world!")); cx.provide_state(MySharedState("world!"));
rsx!(Child {}) cx.render(rsx!(Child {}))
}; };
static Child: FC<()> = |(cx, props)| { static Child: FC<()> = |(cx, props)| {
let shared = cx.consume_state::<MySharedState>()?; let shared = cx.consume_state::<MySharedState>()?;
rsx!("Hello, {shared.0}") cx.render(rsx!("Hello, {shared.0}"))
}; };
let mut dom = VirtualDom::new(App); let mut dom = VirtualDom::new(App);
+14 -13
View File
@@ -19,7 +19,7 @@ use dioxus_html as dioxus_elements;
fn app_runs() { fn app_runs() {
static App: FC<()> = |(cx, props)| { static App: FC<()> = |(cx, props)| {
// //
rsx!( div{"hello"} ) cx.render(rsx!( div{"hello"} ))
}; };
let mut vdom = VirtualDom::new(App); let mut vdom = VirtualDom::new(App);
let edits = vdom.rebuild(); let edits = vdom.rebuild();
@@ -29,10 +29,10 @@ fn app_runs() {
#[test] #[test]
fn fragments_work() { fn fragments_work() {
static App: FC<()> = |(cx, props)| { static App: FC<()> = |(cx, props)| {
rsx!( cx.render(rsx!(
div{"hello"} div{"hello"}
div{"goodbye"} div{"goodbye"}
) ))
}; };
let mut vdom = VirtualDom::new(App); let mut vdom = VirtualDom::new(App);
let edits = vdom.rebuild(); let edits = vdom.rebuild();
@@ -43,10 +43,10 @@ fn fragments_work() {
#[test] #[test]
fn lists_work() { fn lists_work() {
static App: FC<()> = |(cx, props)| { static App: FC<()> = |(cx, props)| {
rsx!( cx.render(rsx!(
h1 {"hello"} h1 {"hello"}
{(0..6).map(|f| rsx!(span{ "{f}" }))} {(0..6).map(|f| rsx!(span{ "{f}" }))}
) ))
}; };
let mut vdom = VirtualDom::new(App); let mut vdom = VirtualDom::new(App);
let edits = vdom.rebuild(); let edits = vdom.rebuild();
@@ -56,11 +56,11 @@ fn lists_work() {
#[test] #[test]
fn conditional_rendering() { fn conditional_rendering() {
static App: FC<()> = |(cx, props)| { static App: FC<()> = |(cx, props)| {
rsx!( cx.render(rsx!(
h1 {"hello"} h1 {"hello"}
{true.then(|| rsx!(span{ "a" }))} {true.then(|| rsx!(span{ "a" }))}
{false.then(|| rsx!(span{ "b" }))} {false.then(|| rsx!(span{ "b" }))}
) ))
}; };
let mut vdom = VirtualDom::new(App); let mut vdom = VirtualDom::new(App);
@@ -73,16 +73,16 @@ fn conditional_rendering() {
#[test] #[test]
fn child_components() { fn child_components() {
static App: FC<()> = |(cx, props)| { static App: FC<()> = |(cx, props)| {
rsx!( cx.render(rsx!(
{true.then(|| rsx!(Child { }))} {true.then(|| rsx!(Child { }))}
{false.then(|| rsx!(Child { }))} {false.then(|| rsx!(Child { }))}
) ))
}; };
static Child: FC<()> = |(cx, props)| { static Child: FC<()> = |(cx, props)| {
rsx!( cx.render(rsx!(
h1 {"hello"} h1 {"hello"}
h1 {"goodbye"} h1 {"goodbye"}
) ))
}; };
let mut vdom = VirtualDom::new(App); let mut vdom = VirtualDom::new(App);
let edits = vdom.rebuild(); let edits = vdom.rebuild();
@@ -92,8 +92,9 @@ fn child_components() {
#[test] #[test]
fn suspended_works() { fn suspended_works() {
static App: FC<()> = |(cx, props)| { static App: FC<()> = |(cx, props)| {
let title = use_suspense(cx, || async { "bob" }, move |cx, f| rsx! { "{f}"}); let title = use_suspense(cx, || async { "bob" }, move |cx, f| todo!());
rsx!("hello" { title }) // let title = use_suspense(cx, || async { "bob" }, move |cx, f| rsx! { "{f}"});
cx.render(rsx!("hello" { title }))
}; };
let mut vdom = VirtualDom::new(App); let mut vdom = VirtualDom::new(App);