-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
How to send message between components inside one app? #270
Comments
It should also be possible to have your root component pass a callback to one of its children via props, which when activated, would cause the main component to change some state that another one of its children rely upon, causing a state change in that child. This works OK in some situations, but fails to be ergonomic when you have a deeply nested component structure, or if you want to neatly encapsulate state within components, and not pass everything via props. Alternatively, you could set up your own custom service that is attached to the The latter would likely contain some code that looks like the following: Receiving componentfn create(_: Self::Properties, context: &mut Env<Context, Self>) -> Self {
...
let callback = context.send_back(
|service_msg: YourServiceMsg| {
Msg::from(service_msg)
},
);
context.your_service.register_cb(callback);
...
} Sending componentfn update(&mut self, msg: Msg, context: &mut Env<Context, Self>) -> ShouldRender {
match msg {
Msg::SendMessageToOtherComponent => {
context.your_service.send(YourServiceMsg::Variant)
}
}
false
} Your Servicepub struct YourService {
// This could be a Collection type if you wanted to support multiple receiving components,
// but this would cause a memory leak if you didn't find a solution to remove
// the callback from the service when the component is destructed.
// Maybe returning a Task from the register_cb fn that when it drops, the service would delete the corresponding callback?
callback: Option<Callback<YourServiceMsg>>
}
pub enum YourServiceMsg {
...
}
impl YourService {
fn send(&mut self, msg: YourServiceMsg) {
if let Some(cb) = self.callback {
cb.emit(msg)
}
}
fn register_cb(&mut self, callback: Callback<YourServiceMsg>) {
self.callback = Some(callback)
}
} |
Great post, thank you! I will try test this. |
Before you go ahead and implement my suggestion, I would like you to know that the typical arrangement for message passing between parent and child components is defined in my first paragraph. The example I typed up should only be used for the rather rare edge case where the components that need to communicate sit far apart in the view "tree". So if you just have a component that is the direct child of another component, go with my first suggestion. EDIT: https://github.com/DenisKolodin/yew/blob/master/examples/custom_components/src/lib.rs#L69 The main https://github.com/DenisKolodin/yew/blob/master/examples/custom_components/src/button.rs#L15 The Button component accepts a callback. https://github.com/DenisKolodin/yew/blob/master/examples/custom_components/src/button.rs#L42 When the |
272: Multi-threading, concurrency, agents r=DenisKolodin a=DenisKolodin This is a series of bold experiments and I really love 💓 this PR. It makes this framework a **multi-threaded** (it's not a joke) and brings actors model everywhere. Now your yew frontend-apps will be more _Erlang_ or _Actix_ apps like 🚀 Also, I've removed a context. Completely! Components simplified. Now it's an actor which you could connect to and interact with messages. Other benefit is your components could interact each other #270 Since this PR will be merged the framework turned into multi-threaded concurrency-friendly frontend framework. Sorry me for buzzwords overload ) It still need Routing #187 and fixes of the most issues. I'll get to that. But extra benefit of this PR: it fixes major emscripten issues #220 Remaining: - [x] Add CHANGELOG.md - [x] Update README.md - [x] Create issue: Send `Connected` notification for `Private` agents (#282) - [x] Create issue: Send `Connected` notification for `Public` agents (#282) - [x] Create issue: Implement `Global` kind of agents (based on `SharedWorker`) (#283) - [x] Create issue: Add components interaction example (#284) Co-authored-by: Denis Kolodin <deniskolodin@gmail.com>
Cross component message passing works great now! Thank you for this amazing work! I think Yew is best frontend experience so far at the moment, even compared to most popular js/ts frameworks. Still I've got a couple more question: Inside the worker, does some api exist to see who is connected to the bridge? Idiomatic way to send inner messages just inside one component is the agent way also ? (or activator or similar thing should be used?) |
To sort of answer your first question: You can see that If you wanted to get fancy with it, you could categorize the IDs into distinct sets by sending a message to the agent that tells it to move it out of the subscriptions hashset and into a more specific one or Option slot. It would conceptually be prone to programmer error (you may forget to send the categorization message after creating the bridge), but you could use this pattern to accomplish seeing what is connected at any time. I don't fully understand your second question. For intra-component communication, you just use the Component::Message. If you want to chain or send multiple messages to the Component's reducer ( |
True, but how to send it just from the code? For example, what I want to do is: Msg::Foo => { |
I think what you want is something like: fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::Foo => {
let data = 1 + 2;
self.update(Msg::Bar(data));
false
}
Msg::Bar(_data) => {
// Do something with data
true
}
}
} |
AH, I thought calling update is not really valid option! Thx! |
I'm finding this discussion helpful 3 years on. @hgzimmerman what happened to the custom_components example? I'd like to have a look, but it seems to have disappeared leaving only the pub_sub example. |
Sorry post in this closed issue. I wonder if there is already a built in way to do this task. Is it |
THere is agent functionality now, check some examples or docs. If you will have any questions post here again.
… 14 июня 2021 г., в 05:43, 王世达 ***@***.***> написал(а):
Sorry post in this closed issue. I wonder if there is already a built in way to do this task. Is it Scope?
—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub <#270 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ACCRBG5JDTVCF4M76YWUZHTTSVUE3ANCNFSM4FDJMELA>.
|
In the two apps example, there are two activators which are used for sending messages.
So if I understand correctly all components must share main app Msg type? Or there is other way?
The text was updated successfully, but these errors were encountered: