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

Tips about component communication #2197

Open
Tracked in #2753
Madoshakalaka opened this issue Nov 25, 2021 · 2 comments · May be fixed by #2551
Open
Tracked in #2753

Tips about component communication #2197

Madoshakalaka opened this issue Nov 25, 2021 · 2 comments · May be fixed by #2551

Comments

@Madoshakalaka
Copy link
Contributor

@Madoshakalaka Madoshakalaka commented Nov 25, 2021

This is about:

  • Other (Important Tips)

Component communication might deserve a dedicated page.

Ancestor -> Descendant

straightforward: passing props. Using a context if the descendants can be too deep down the tree.

Descedant -> Ancestor

This is not very obvious. In fact, two people asked the same question on Discord in one day. And personally, I had no clue either despite having deployed a Yew app to production (yep it was all Agents & Yewdux....yep I didn't read the docs...yep it was crazy boilerplate...).

The proper way to do this is passing a callback in the props and using Callback::emit in the descendant.

Here's an example of a <Son/> which consumes a callback from the <Dad/>, the <Son/> renders a button, and when the button is clicked, the <Dad/> element will receive a message.

#[function_component(Dad)]
fn dad() -> Html {
    let onclick = Callback::from(|message: String|{
        gloo_console::log!("dad got the message: ", message);
    });
    html! {
        <Son {onclick}></Son>
    }
}


#[derive(Properties, PartialEq)]
pub struct SonProps {
    onclick: Callback<String>
}

#[function_component(Son)]
pub fn son(props: &SonProps) -> Html {

    let onclick = props.onclick.clone();
    let onclick = move |_|{
        onclick.emit("Hi Dad".to_string());
    };

    html! {
        <button {onclick}>{"clicky clicky"}</button>
    }
}

fn main() {
    yew::start_app::<Dad>();
}

Same with the ancestor->descendant direction. When the descendant is too deep down the tree, passing props can lead to too much code. Using context can help. (Should be possible, haven't tried, need code)

In function components, instead of passing callbacks, using use_reducer and passing the UseReducerDispatcher acquired by reducer_handle.dispatcher() should be favored

When the components are not in the same VDom tree

when the components are not in the same Vdom tree for callbacks to be passed around. An Agent should be used (hey, this pub_sub example isn't even mentioned in the docs.)

Alternatives state management tools like yewdux and bounce can also be used. (alright the second one is a bit new but I'm @futursolo shill, no shame)

@mc1098
Copy link
Contributor

@mc1098 mc1098 commented Nov 25, 2021

straightforward: passing props. Using a context if the descendants can be too deep down the tree.

You may find that #905 is related to this topic too.

@hamza1311
Copy link
Member

@hamza1311 hamza1311 commented Jan 1, 2022

#2321 adds a section about component communication (see here). It only mentions props for parent to child communication and suggests using contexts for everything else.

As suggested in this issue, we need to expand upon this. A good first step will be to add a section about passing callbacks as props and emiting to them. In that section, we could also mention that this is how we communicate from child to parent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants