Panic when child's view function sets parent's state
Problem This setup causes a panic:
#[function_component(Parent)]
pub fn parent() -> Html {
let shared_state = use_state(|| String::default());
html{
<Child shared_state={shared_state.clone()} />
}
}
// snip child props
#[function_component(Child)]
pub fn child(props: &ChildProps) -> Html {
props.shared_state.set(...);
html!{ ... }
}
The following is printed in the JS console:
panicked at 'failed to insert tag before next sibling: JsValue(NotFoundError: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
Error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
at http://localhost:8000/index-c9e434318a5c50d9.js:620:35
at handleError (http://localhost:8000/index-c9e434318a5c50d9.js:278:18)
at imports.wbg.__wbg_insertBefore_5b314357408fbec1 (http://localhost:8000/index-c9e434318a5c50d9.js:619:75)
at web_sys::features::gen_Node::Node::insert_before::hf68c86e22a059500 (http://localhost:8000/index-c9e434318a5c50d9_bg.wasm:wasm-function[10321]:0xa2d471)
at yew::virtual_dom::insert_node::h24c5fb007c92d0d0 (http://localhost:8000/index-c9e434318a5c50d9_bg.wasm:wasm-function[10452]:0xa373ae)
at yew::html::component::scope::Scope<COMP>::mount_in_place::hebcbbbc0ce7721f3 (http://localhost:8000/index-c9e434318a5c50d9_bg.wasm:wasm-function[1868]:0x5adfa4)
at <yew::virtual_dom::vcomp::PropsWrapper<COMP> as yew::virtual_dom::vcomp::Mountable>::mount::h70cd3f0b7fb28805 (http://localhost:8000/index-c9e434318a5c50d9_bg.wasm:wasm-function[5408]:0x85bb34)
at <yew::virtual_dom::vcomp::VComp as yew::virtual_dom::VDiff>::apply::h15ca06697f33d0e6 (http://localhost:8000/index-c9e434318a5c50d9_bg.wasm:wasm-function[1577]:0x553816)
at <yew::virtual_dom::vnode::VNode as yew::virtual_dom::VDiff>::apply::hddcbafeaa916b552 (http://localhost:8000/index-c9e434318a5c50d9_bg.wasm:wasm-function[600]:0x36ad9d)
at <yew::html::component::lifecycle::RenderRunner<COMP> as yew::scheduler::Runnable>::run::h1ec6b91d9034b4be (http://localhost:8000/index-c9e434318a5c50d9_bg.wasm:wasm-function[1382]:0x50e821))', /home/felix/.cargo/registry/src/github.com-1ecc6299db9ec823/yew-0.19.3/src/virtual_dom/mod.rs:536:14
I understand this is not a good place to be setting state and I don't actually do this, but mention it anyway as it's a panic.
Environment:
- Yew version: 0.19.3
- Rust version: nightly
- Target, if relevant: wasm32-unknown-unknown
- Build tool, if relevant: trunk
- OS, if relevant: Ubuntu
- Browser and version, if relevant: Brave 1.37.116
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
- [x] I don't have time to fix this right now, but maybe later
~~Does work on master, so we I think we'd have to find out which patch to back-port if we want to support this.~~
EDIT: The following works also with yew 0.19.3. Can you please submit a full example without omissions, since I can't reproduce this
use yew::prelude::*;
#[function_component(Parent)]
pub fn parent() -> Html {
let shared_state = use_state(String::default);
html! {
<Child {shared_state} />
}
}
#[derive(PartialEq, Properties)]
pub struct ChildProps {
shared_state: UseStateHandle<String>,
}
#[function_component(Child)]
pub fn child(props: &ChildProps) -> Html {
props.shared_state.set("child rendered".to_string());
html! { <p>{"Content"}</p> }
}
fn main() {
yew::start_app::<Parent>();
}
I am running in the same issue (yew 0.19.3). I am however not really what triggers this:
console log
14:59:38.282
panicked at 'failed to insert tag before next sibling: JsValue(NotFoundError: Node.insertBefore: Child to insert before is not a child of this node
init/imports.wbg.__wbg_insertBefore_4df558a2aa0435c1/<@https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:1009:37
handleError@https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:300:18
init/imports.wbg.__wbg_insertBefore_4df558a2aa0435c1@https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:1008:75
yew::virtual_dom::insert_node::hc98bcb53cccf2b6b@https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:wasm-function[2844]:0x2875b9
<yew::virtual_dom::vnode::VNode as yew::virtual_dom::VDiff>::apply::h6b2d3d96d0f21ff7@https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:wasm-function[283]:0xd8ad6
yew::virtual_dom::vlist::VList::apply_unkeyed::h7b9dd45a5f73051b@https://…
index-1b2503aa9c5587df.js:570:21
14:59:38.283 Uncaught RuntimeError: unreachable executed
index-1b2503aa9c5587df_bg.wasm:3020460:1
rust_panic https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:3020460
h623ac32ff431b114 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2564502
h4939ceabc7a11060 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2721158
h9f6add6df687a1bf https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:3010687
rust_begin_unwind https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:3002090
h5118e89563022e7e https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2969850
ha62420c192a556da https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2763334
hc98bcb53cccf2b6b https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2651679
<yew::virtual_dom::vnode::VNode as yew::virtual_dom::VDiff>::apply::h6b2d3d96d0f21ff7 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:887510
h7b9dd45a5f73051b https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2114283
<yew::virtual_dom::vlist::VList as yew::virtual_dom::VDiff>::apply::h6612d2aa867ffde0 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:587337
<yew::virtual_dom::vnode::VNode as yew::virtual_dom::VDiff>::apply::h6b2d3d96d0f21ff7 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:888279
h7b9dd45a5f73051b https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2114283
<yew::virtual_dom::vlist::VList as yew::virtual_dom::VDiff>::apply::h6612d2aa867ffde0 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:587337
<yew::virtual_dom::vnode::VNode as yew::virtual_dom::VDiff>::apply::h6b2d3d96d0f21ff7 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:888279
<yew::html::component::lifecycle::RenderRunner<COMP> as yew::scheduler::Runnable>::run::hf92193f77819ab97 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:1564386
h0702569f943302de https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2487935
h5cb0843ffa0db5c4 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2491585
h9e3f0c07ced32b82 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2985293
hb712fa27f1a3499f https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2673324
<yew::html::listener::events::onclick::Wrapper as yew::virtual_dom::listeners::Listener>::handle::h00b0e7d3369eb373 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:3012326
hb7c0947cba63d3a1 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:1553730
hc6c615f8d9ff7bec https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2511153
<dyn core::ops::function::Fn<(A,)>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::hc7ade49fe9e80292 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2994115
__wbg_adapter_58 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:295
real https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:265
(Async: EventListener.handleEvent)
__wbg_addEventListener_be0c061a1359c1dd https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:890
handleError https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:300
__wbg_addEventListener_be0c061a1359c1dd https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:889
h59825fc6ca316a39 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2971068
h081b10d8d39b2b0a https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:1502243
hb69bf4b01d097692 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:1355321
<yew::virtual_dom::vnode::VNode as yew::virtual_dom::VDiff>::apply::h6b2d3d96d0f21ff7 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:890592
h7b9dd45a5f73051b https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2113902
<yew::virtual_dom::vlist::VList as yew::virtual_dom::VDiff>::apply::h6612d2aa867ffde0 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:587337
<yew::virtual_dom::vnode::VNode as yew::virtual_dom::VDiff>::apply::h6b2d3d96d0f21ff7 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:890825
h7b9dd45a5f73051b https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2113902
<yew::virtual_dom::vlist::VList as yew::virtual_dom::VDiff>::apply::h6612d2aa867ffde0 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:587337
<yew::virtual_dom::vnode::VNode as yew::virtual_dom::VDiff>::apply::h6b2d3d96d0f21ff7 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:890825
h7b9dd45a5f73051b https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2113902
<yew::virtual_dom::vlist::VList as yew::virtual_dom::VDiff>::apply::h6612d2aa867ffde0 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:587337
<yew::virtual_dom::vnode::VNode as yew::virtual_dom::VDiff>::apply::h6b2d3d96d0f21ff7 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:890825
h7b9dd45a5f73051b https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2113902
<yew::virtual_dom::vlist::VList as yew::virtual_dom::VDiff>::apply::h6612d2aa867ffde0 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:587337
<yew::virtual_dom::vnode::VNode as yew::virtual_dom::VDiff>::apply::h6b2d3d96d0f21ff7 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:890825
<yew::html::component::lifecycle::RenderRunner<COMP> as yew::scheduler::Runnable>::run::h7a6f45d6033e41e1 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:833161
h0702569f943302de https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2487935
hd71178e89728d91d https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2655981
h0ea7833680d41994 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2928757
<core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h7e928ef3256a2743 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2054682
h6adae2f65af01e7e https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2264945
<dyn core::ops::function::FnMut<(A,)>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h25183630db808d31 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2994016
__wbg_adapter_55 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:291
real https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:202
(Async: promise callback)
__wbg_then_ce526c837d07b68f https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:856
hb48e4c009766a028 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2519219
h2f0a3d325e57256e https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2858905
h335cd0490da6cfe2 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2861577
<wasm_bindgen_futures::JsFuture as core::convert::From<js_sys::Promise>>::from::finish::hc421782b42cf9828 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2570844
<T as wasm_bindgen::closure::WasmClosureFnOnce<A,R>>::into_fn_mut::{{closure}}::h20805aaaa86cd129 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2897841
<dyn core::ops::function::FnMut<(A,)>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h25183630db808d31 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2994016
__wbg_adapter_55 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:291
real https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:202
(Async: promise callback)
__wbg_then_842e65b843962f56 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:852
<wasm_bindgen_futures::JsFuture as core::convert::From<js_sys::Promise>>::from::h71cef0d09f71b62b https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2456726
<core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::hb3e695b88e0fb507 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2163820
<core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h5ea5cbda1d07045e https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:1031371
<core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h8a8fa2d46c140836 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:111433
<core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h7e928ef3256a2743 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2054470
h6adae2f65af01e7e https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2264945
<dyn core::ops::function::FnMut<(A,)>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h25183630db808d31 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2994016
__wbg_adapter_55 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:291
real https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:202
(Async: promise callback)
__wbg_then_ce526c837d07b68f https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:856
hb48e4c009766a028 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2519219
h2f0a3d325e57256e https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2858905
h335cd0490da6cfe2 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2861577
<wasm_bindgen_futures::JsFuture as core::convert::From<js_sys::Promise>>::from::finish::hc421782b42cf9828 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2570844
<T as wasm_bindgen::closure::WasmClosureFnOnce<A,R>>::into_fn_mut::{{closure}}::h20805aaaa86cd129 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2897841
<dyn core::ops::function::FnMut<(A,)>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h25183630db808d31 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2994016
__wbg_adapter_55 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:291
real https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:202
(Async: promise callback)
__wbg_then_842e65b843962f56 https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df.js:852
<wasm_bindgen_futures::JsFuture as core::convert::From<js_sys::Promise>>::from::h71cef0d09f71b62b https://console-drogue-dev.apps.wonderful.iot-playground.org/index-1b2503aa9c5587df_bg.wasm:2456726
I just got the same panic and managed to produce a minimal example:
use yew::prelude::*;
fn main() {
yew::start_app::<Model>();
}
#[function_component(Model)]
fn test() -> html {
let state = use_state(|| (true, false));
let cb = {
let state = state.clone();
Callback::from(move |_| {
state.set((false, true));
})
};
html! {
<div>
<button onclick={cb}>{"Click me"}</button>
<Text display={state.0}/>
<Text display={state.1}/>
</div>
}
}
#[derive(Properties, PartialEq)]
struct Props {
display: bool,
}
#[function_component(Text)]
fn text(props: &Props) -> html {
if props.display {
html! { <p> {"Hello"} </p> }
} else {
html! {}
}
}
Pressing "click me" triggers the panic. As I understand it, the problem seems to be removing and adding a child element at the same time. Yew tries to add the new child after the previous child, but the previous child doesn't exist anymore.
Just found #2859. So can probably be closed in favor for the other one, which describes workarounds.