1use anymap2::AnyMap;
2use yew::prelude::*;
3
4use crate::root_state::BounceRootState;
5
6#[derive(Properties, Debug, PartialEq, Clone)]
8pub struct BounceRootProps {
9 #[prop_or_default]
11 pub children: Children,
12
13 #[prop_or_default]
19 pub get_init_states: Option<Callback<(), AnyMap>>,
20}
21
22#[function_component(BounceRoot)]
44pub fn bounce_root(props: &BounceRootProps) -> Html {
45 let BounceRootProps {
46 children,
47 get_init_states,
48 } = props.clone();
49
50 let root_state = (*use_state(move || {
51 let init_states = get_init_states.map(|m| m.emit(())).unwrap_or_default();
52 BounceRootState::new(init_states)
53 }))
54 .clone();
55
56 #[allow(clippy::redundant_clone)]
57 {
58 let root_state = root_state.clone();
59 use_effect_with((), move |_| {
60 move || {
62 root_state.clear();
63 }
64 });
65 }
66
67 #[allow(clippy::unused_unit, clippy::redundant_clone)]
68 {
69 let _root_state = root_state.clone();
70 let _ = use_transitive_state!((), move |_| -> () {
71 #[cfg(feature = "ssr")]
72 #[cfg(feature = "helmet")]
73 {
74 use crate::helmet::StaticWriterState;
76
77 let states = _root_state.states();
78 let writer_state = states.get_atom_value::<StaticWriterState>();
79
80 if let Some(ref w) = writer_state.writer {
81 w.send_helmet(
82 states,
83 writer_state.format_title.clone(),
84 writer_state.default_title.clone(),
85 );
86 }
87 }
88
89 _root_state.clear();
91 });
92 }
93
94 html! {
95 <ContextProvider<BounceRootState> context={root_state}>{children}</ContextProvider<BounceRootState>>
96 }
97}