-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Problem
When a VTag is reused the ancestor's NodeRef doesn't get reset and therefore will continue pointing to the Element in the reused VTag. This is often not a problem, however, when conditionally rendering and using NodeRef on both this can lead to editing a Element reference with a NodeRef that was set to the ancestor VTag. (see the example below)
Steps To Reproduce
use yew::prelude::*;
pub struct Comp {
show_a: bool,
node_ref_a: NodeRef,
node_ref_b: NodeRef,
}
impl Component for Comp {
type Message = ();
type Properties = ();
fn create(_: &Context<Self>) -> Self {
Self {
show_a: true,
node_ref_a: Default::default(),
node_ref_b: Default::default(),
}
}
fn update(&mut self, _: &Context<Self>, _: Self::Message) -> bool {
self.show_a = !self.show_a;
true
}
fn view(&self, ctx: &Context<Self>) -> Html {
let (t, node) = if self.show_a {
("a", html! { <div id="a" ref={self.node_ref_a.clone()} /> })
} else {
("b", html! { <div id="b" ref={self.node_ref_b.clone()} /> })
};
let onclick = ctx.link().callback(|_| ());
html! {
<>
{t}
{node}
<button {onclick}>{ "Click me" }</button>
</>
}
}
fn rendered(&mut self, _: &Context<Self>, first_render: bool) {
if first_render {
return;
}
if !self.show_a {
// This should never be Some!
if let Some(node) = self.node_ref_a.get() {
// node_ref_a here is actually referencing node b!
node.set_text_content(Some("hello b!"));
}
}
}
}First render is fine, the second after pressing the button will render the "b" div and then rendered will run and even though it's using the node_ref_a it will return a Some with the reference to the "b" div and the content will be updated to display "hello b!".
Expected behavior
That the ancestors NodeRef is reset when the Element is being reused, this simply means updating the ancestors NodeRef and setting the inner Option<Node> to None.
When working correctly the example will never set the text content for either div "a" or "b" to "hello b!".
Environment:
- Yew version:
master
Questionnaire
- I'm interested in fixing this myself but don't know where to start
- I would like to fix and I have a solution
- I don't have time to fix this right now, but maybe later