Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delay Hydration second render until all assistive nodes have been removed #2629

Merged
merged 22 commits into from
Apr 24, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/js_callback/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"

[dependencies]
wasm-bindgen = "0.2"
yew = { path = "../../packages/yew", features = ["csr"] }
yew = { path = "../../packages/yew", features = ["csr", "tokio"] }
hamza1311 marked this conversation as resolved.
Show resolved Hide resolved
wasm-bindgen-futures = "0.4"
js-sys = "0.3"
once_cell = "1"
54 changes: 8 additions & 46 deletions packages/yew/src/dom_bundle/bcomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ use web_sys::Element;
pub(super) struct BComp {
type_id: TypeId,
scope: Box<dyn Scoped>,
// A internal NodeRef passed around to track this components position. This
// is "stable", i.e. does not change when reconciled.
internal_ref: NodeRef,
// The user-passed NodeRef from VComp. Might change every time we reconcile.
// Gets linked to the internal ref
node_ref: NodeRef,
key: Option<Key>,
}
Expand Down Expand Up @@ -62,23 +57,20 @@ impl Reconcilable for VComp {
node_ref,
key,
} = self;
let internal_ref = NodeRef::default();
node_ref.link(internal_ref.clone());

let scope = mountable.mount(
root,
internal_ref.clone(),
node_ref.clone(),
parent_scope,
parent.to_owned(),
next_sibling,
);

(
internal_ref.clone(),
node_ref.clone(),
BComp {
type_id,
node_ref,
internal_ref,
key,
scope,
},
Expand Down Expand Up @@ -120,10 +112,10 @@ impl Reconcilable for VComp {
} = self;

bcomp.key = key;
let old_ref = std::mem::replace(&mut bcomp.node_ref, node_ref);
let old_ref = std::mem::replace(&mut bcomp.node_ref, node_ref.clone());
bcomp.node_ref.reuse(old_ref);
mountable.reuse(bcomp.scope.borrow(), next_sibling);
bcomp.internal_ref.clone()
mountable.reuse(node_ref.clone(), bcomp.scope.borrow(), next_sibling);
node_ref
}
}

Expand All @@ -147,24 +139,21 @@ mod feat_hydration {
node_ref,
key,
} = self;
let internal_ref = NodeRef::default();
node_ref.link(internal_ref.clone());

let scoped = mountable.hydrate(
root.clone(),
parent_scope,
parent.clone(),
fragment,
internal_ref.clone(),
node_ref.clone(),
);

(
internal_ref.clone(),
node_ref.clone(),
BComp {
type_id,
scope: scoped,
node_ref,
internal_ref,
key,
},
)
Expand All @@ -176,7 +165,7 @@ mod feat_hydration {
#[cfg(test)]
mod tests {
use super::*;
use crate::dom_bundle::{Bundle, Reconcilable, ReconcileTarget};
use crate::dom_bundle::{Reconcilable, ReconcileTarget};
use crate::scheduler;
use crate::{
html,
Expand Down Expand Up @@ -453,33 +442,6 @@ mod tests {
scheduler::start_now();
assert!(node_ref.get().is_none());
}

#[test]
fn reset_ancestors_node_ref() {
let (root, scope, parent) = setup_parent();

let mut bundle = Bundle::new();
let node_ref_a = NodeRef::default();
let node_ref_b = NodeRef::default();
let elem = html! { <Comp ref={node_ref_a.clone()}></Comp> };
let node_a = bundle.reconcile(&root, &scope, &parent, NodeRef::default(), elem);
scheduler::start_now();
let node_a = node_a.get().unwrap();

assert!(node_ref_a.get().is_some(), "node_ref_a should be bound");

let elem = html! { <Comp ref={node_ref_b.clone()}></Comp> };
let node_b = bundle.reconcile(&root, &scope, &parent, NodeRef::default(), elem);
scheduler::start_now();
let node_b = node_b.get().unwrap();

assert_eq!(node_a, node_b, "Comp should have reused the element");
assert!(node_ref_b.get().is_some(), "node_ref_b should be bound");
assert!(
node_ref_a.get().is_none(),
"node_ref_a should have been reset when the element was reused."
);
}
futursolo marked this conversation as resolved.
Show resolved Hide resolved
}

#[cfg(feature = "wasm_test")]
Expand Down
2 changes: 1 addition & 1 deletion packages/yew/src/dom_bundle/blist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ mod feat_hydration {
let (child_node_ref, child) = child.hydrate(root, parent_scope, parent, fragment);

if index == 0 {
node_ref.link(child_node_ref);
node_ref.reuse(child_node_ref);
}

children.push(child);
Expand Down
5 changes: 1 addition & 4 deletions packages/yew/src/dom_bundle/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ pub(super) fn insert_node(node: &Node, parent: &Element, next_sibling: Option<&N
match next_sibling {
Some(next_sibling) => parent
.insert_before(node, Some(next_sibling))
.unwrap_or_else(|err| {
gloo::console::error!("failed to insert node", err, parent, next_sibling, node);
panic!("failed to insert tag before next sibling")
}),
.expect("failed to insert tag before next sibling"),
None => parent.append_child(node).expect("failed to append child"),
};
}
Expand Down