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

Examples for complex cases with useState hook #347

Open
Tagir-A opened this issue Mar 10, 2023 · 9 comments
Open

Examples for complex cases with useState hook #347

Tagir-A opened this issue Mar 10, 2023 · 9 comments
Assignees
Labels

Comments

@Tagir-A
Copy link

Tagir-A commented Mar 10, 2023

Describe what scenario you think is uncovered by the existing examples/articles

Hello! I'm new to Dart and Flutter, but I've used React a lot. Since this library is a port of React hooks, I'd suggest to provide more examples of how hooks could be used. Especially the cases, where it's different from react.
I'd suggest to have an example section, which could be filled with the help of the community.

Describe why existing examples/articles do not cover this case

I struggle to understand even such a simple hook as useState in Flutter.
It seems that Dart (or Flutter, or this library) behave different from React hooks when complex objects are passed.

For example, I specifically struggle with this situation:
I have a Sealed Union built by freezed as a representation of the state.
When the exercise prop is passed, I expect the state to initialise.
This works for the render of the widget. However, after the exercise prop changes in the parent widget, the state keeps the previous value.

I'm not sure what is the issue. Maybe I misunderstand how Flutter works, but I'd definitely expect the desired behaviour in React.

Code for reference:

// ...
@freezed
class Answer with _$Answer {
  const factory Answer.valid(String value) = Valid;
  const factory Answer.invalid(String value) = Invalid;
}

@freezed
class FormState with _$FormState {
  const factory FormState.initial(MultipleChoiceExercise exercise) = Initial;
  const factory FormState.answered(Answer answer) = Answered;
  const factory FormState.showingCorrect(
      Answer answer, MultipleChoiceExercise exercise) = ShowingCorrect;
}

class MultipleChoiceForm extends HookWidget {
  final MultipleChoiceExercise exercise;

  const MultipleChoiceForm({
    required this.exercise,
// ...
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final formState = useState<FormState>(FormState.initial(exercise));
    // ...

It would be wonderful to have complex cases as examples somewhere in the docs.
I'd gladly contribute myself, if you agree with the notion proposed.

@rrousselGit
Copy link
Owner

When the exercise prop is passed, I expect the state to initialise.
This works for the render of the widget. However, after the exercise prop changes in the parent widget, the state keeps the previous value.

What does that mean exactly? I do not understand this bit.

@rrousselGit rrousselGit added question Further information is requested and removed needs triage labels Mar 10, 2023
@Tagir-A
Copy link
Author

Tagir-A commented Mar 10, 2023

I'll try to explain, using React references. Again, I'm very new to Flutter and Dart, sorry about that.

In react, when I pass an object like so

const [someObject, setSomeObject] = useState({})
return <MultipleChoiceForm exercise={someObject} />

the child re-renders when that object is replaced in the parent. For example:

// Parent code
setSomeObject(newObject)

will trigger a re-render of <MultipleChoiceForm exercise={someObject} />
so inside child it would trigger a new state initialiser.

// MultipleChoiceForm code
const [formState] = useState(FormState.initial(exercise));

I tried to do the same in Flutter. But it's not working. I receive an updated prop inside widget, but it does not trigger a state initialiser for the hook.

I hope now the problem is more clear.

@rrousselGit
Copy link
Owner

You mean that if useState(false) changes to useState(true), the state resets?

@rrousselGit
Copy link
Owner

The state never resets for me on React.

Maybe you're confused and your state was reset for reset reasons? Like tree shape change or key change, which causes the component to be unmounted.

@Tagir-A
Copy link
Author

Tagir-A commented Mar 10, 2023

You mean that if useState(false) changes to useState(true), the state resets?

No, I mean if you have useState(props.someProp), it will reset, when the prop is updated.

@rrousselGit
Copy link
Owner

That's what I meant. I tried and didn't see this behavior.

Do you maybe have a react example?

@Tagir-A
Copy link
Author

Tagir-A commented Mar 10, 2023

Okay, I feel like I made a mistake there. I'll update once I've done investigating.

@Tagir-A
Copy link
Author

Tagir-A commented Mar 10, 2023

Indeed you were right. I was confused about React behaviour.
Thanks for your help!

However, what do you think about adding more examples?
I really feel like there could be a whole "examples" section to highlight good patterns, explain bad patterns and promote a better alternative, explain integrations with some other popular tools.

I understand that mostly we can look at react examples, but it wouldn't hurt to have specific Flutter examples, right?

@rrousselGit
Copy link
Owner

I don't have time to work on examples. Feel free to contribute some if you want to.

@rrousselGit rrousselGit self-assigned this May 10, 2023
@rrousselGit rrousselGit added good first issue Good for newcomers and removed question Further information is requested labels May 24, 2023 — with Volta.net
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants