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

Fix diffing issue with pure stateless components #1309

Merged
merged 3 commits into from
Apr 19, 2022

Conversation

nicksenger
Copy link
Contributor

Currently there is an issue with diffing pure stateless components because the implementation of diff for component::Instance will attempt to downcast a State::None in certain situations.

Generally this will happen when diffing a tree node which previously belonged to any stateless widget with what is now a stateless component. Because the stateless component's tag matches that of any other stateless widget, we will call diff and attempt to downcast even though the state is (). I've put a repro case for this here: https://gist.github.com/nicksenger/2572dc018299f8db2fa293b002ccbe6b

This fix is to simply change the implementation of tag so that it returns a Tag specific to components, even if the component is stateless.

Copy link
Member

@hecrj hecrj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch! Thanks again!

What are you using stateless components for?

@hecrj hecrj merged commit a0ade54 into iced-rs:master Apr 19, 2022
@nicksenger
Copy link
Contributor Author

What are you using stateless components for?

I've found a few uses for them so far:

  1. I want to wrap various parts of my view so that pressing arrow keys is captured under certain conditions, and I don't necessarily want to do anything with them. Using a stateless component I can put this behavior wherever I want pretty easily, and don't need a new message variant at the application level for it. I suppose a custom widget could do the same thing, but using component is shorter/easier than implementing widget if the parts are already available.
  2. "Headless" components that just encapsulate some update logic. For example I have a headless number input with events InputChanged(String), Increment, and Decrement, but I don't want it to have any opinion about what it looks like, and its value is still owned at the application level. The user provides the view that produces these events, and they'll get change messages from the component with the new value without having to wire anything up in the application update.
  3. The component's update can read data passed in when creating the component in the application's view, and use it to defer some computation that you wouldn't necessarily want to do on every view to produce a message.
  4. Some (potentially hacky) situations where state needs to be mutated in view (through a RefCell) as well as update, but the state still needs to be owned at the application level.

It seems like 1-3 are really about keeping complexity out of the application update, so maybe that's the general thing I'm using them for. 4 is a weird application-specific case that's probably better solved through the persistent widget tree.

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

Successfully merging this pull request may close these issues.

2 participants