-
-
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
Add a method to emit multiple messages in one callback #660
Conversation
For reference, the existing pattern to accomplish multiple message dispatch per received message is: pub enum Msg {
SetPosts(Vec<Post>),
SetPagination(u32,u32,u32),
HandleResponse(Response<Json<Result<PostResult, Error>>>),
FetchPosts
}
// ...
fn update(&mut self, msg: self::Message) -> ShouldRender {
match msg {
Msg::HandleResponse(response) => {
if let PostResult(posts, page, per_page, last_page) = body {
self.update(Msg::SetPosts(posts));
self.update(Msg::SetPagination(page, per_page, last_page));
true
} else {
false
}
}
Msg::SetPosts(posts) => {},
Msg::SetPagination(page, per_page, last_page) => {}
Msg::FetchPosts => {
let request = unimplemented!();
let callback = self.link.send_back(HandleResponse);
self.task = Some(self.fetch_service.fetch(request, callback));
false
}
}
} |
@hgzimmerman it's a really cool solution! However, in my opinion, It is unnecessary to create a new Message ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stkevintan looks good to me, the dispatched messages will be processed sequentially by the scheduler. Only thing is that you could possibly render for each dispatch call when you would probably prefer to only render once, which is bad for performance.
I think we can add a new method send_messages
to Scope
for sending multiple messages at once. ComponentUpdate::Message
can be changed to a list of messages. Then only need to render once and the user does not need to worry. What do you think?
I like @jstarry's proposed solution. It keeps terminal-message specification close to the site of where the callback is created, and keeps additional rerendering to a minimum. To quickly rewrite the initial proposed code with jstarry's suggestions in mind: let callback = self.link.send_back_many(|response: Response<Json<Result<PostResult, Error>>>| {
let (header, Json(body)) = response.into_parts();
if let PostResult(posts, page, per_page, last_page) = body {
vec![Msg::SetPosts(posts), Msg::SetPagination((page, per_page, last_page)]
} else {
vec![Msg::GetPostsFailed]
}
} If we want to prematurely over-optimize this a little bit, then I would suggest defining: enum SingleOrMany<T> {
Single(T),
Many(Vec<T>)
} to use for the internal representation in |
@jstarry @hgzimmerman Sorry for delay. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking much cleaner!! Just some naming changes and then good to go
@stkevintan can you please run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
谢谢!
@jstarry You're welcome~ 🤣 |
* feat: add create_effect method to help create effect callback * style: fmt code with rustfmt * feat: support bunch update in one render loop * typo: change bunch to batch * style: fmt with cargo
Currently, the
send_back
method can only trigger one message as the callback return. but there are many common case that need trigger multiple messages, like:I fetch a post list from server using FetchService, but I cannot fetch all the posts at once, the common way is using a
pagination
, so suppose I have following two messages:So it's necessary to trigger the two Message when the request is done.
send_back
cannot do this becauseCallback
only allow to return one Message, so I create thecreate_effect
method.There is a work example in my blog source: kirk
This solution is much like redux-thunk
Besides , I am not sure to determine wether to update the
send_back
method directly or create a new one. maybe adding a new method is the wise choice which will not cause a break change.