Description
It would be helpful if the Book and API docs would make it clear how long state values created by Bounce live for.
I assume for basic Atom
s, once you use them once they live for the full lifetime of the BounceRoot
(is that true though?), which is why I want to focus on InputSelector
and Query
which are slightly less clear.
The documentation says that input selectors and queries are recalculated if the input changes, but the documentation for input selector also says "Each selector with a different input are treated as a different selector.", which sounds like InputSelector
are keyed on values not just on types.
What happens when you change the input for an InputSelector
or Query
hook? Is the old value of the selector/query dropped? How does that work if I have two different components using the same InputSelector
/Query
but with different inputs?
My biggest concern is that I don't want to create a memory leak by repeatedly changing the input value for an InputSelector
or Query
and having the BounceRoot
accumulate a massive cache of values with other old inputs just in case I use them again, though it would also be helpful to understand how InputSelector
and Query
work when there are different components sending different inputs, since I also wouldn't want to have the value repeatedly recalculated due to different components sending different inputs.
Examples:
#[derive(Properties, PartialEq)]
struct Props {
user_id: Rc<u64>,
}
#[function_component]
fn GreetUser(props: &Props) -> Html {
let user = use_query_value::<UserQuery>(props.user_id.clone());
match user.result() {
// The result is None if the query is currently loading.
None => html! {<div>{"loading..."}</div>},
// The result is Some(Ok(_)) if the query has loaded successfully.
Some(Ok(m)) => html! {<div>{"User's name is "}{m.value.name.to_string()}</div>},
// The result is Some(Err(_)) if an error is returned during fetching.
Some(Err(e)) => html! {<div>{"Oops, something went wrong."}</div>},
}
}
// Suppose I have an input that selects between different user_id values and pass them
// down to the `GreetUser` component.
#[function_component]
fn UserSelection() -> Html {
let selected_user = use_state(|| 0);
// Every time this on-click fires, we will re-render `GreetUser` with a new input prop
// for `user_id`, which will then be passed to `use_query_value`.
//
// What will happen to the old `User` value from the `UserQuery` after each
// increment? Will it stay cached in the `BounceRoot` or will it get dropped?
let onclick = {
let selected_user = selected_user.clone();
Callback::from(move |_| selected_user.set(*selected_user + 1))
};
html! {
<div>
<button {onclick}>{ "Next User" }</button>
<GreetUser user_id={Rc::new(*selected_user)} />
</div>
}
}
// Suppose I try to run the same query with multiple different inputs at the same time:
html! {
<div>
// I assume this will "just work" and each greeter will run its query independently,
// but it would be good if the documentation was more explicit about how inputs
// to `InputSelector` and `Query` interact with their caching.
<GreetUser user_id={Rc::new(0)} />
<GreetUser user_id={Rc::new(1)} />
</div>
}