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

Custom hooks: How to reset state when inputs are updated? #14288

Closed
peterjuras opened this issue Nov 20, 2018 · 5 comments
Closed

Custom hooks: How to reset state when inputs are updated? #14288

peterjuras opened this issue Nov 20, 2018 · 5 comments

Comments

@peterjuras
Copy link

Do you want to request a feature or report a bug?

Probably a feature, I'd like to know why the useState hook does not have a second argument to compare inputs similar to other hooks.

What is the current behavior?

I'm trying to implement custom hooks for a timer and countdown library that we use at work. However, for this example I would like to describe a more minimal example with a counter that counts up from a provided initial value.

I created a small fiddle with a custom hook useCountUp that takes an initial value and increments it each second. The counter should reset itself, when the initialValue that is passed to the custom hook changes. As the fiddle demonstrates, it is currently not really possible to reset the state of the useState hook. As a hack, the hook compares the inputs in a useMemo function and updates the state in the next useEffect run. This however, leads to a duplicate render, which would not be necessary.

My question: Why did the useState hook API not receive a second argument to use reset the state to the provided initalValue when certain inputs change, similar to useMemo, useEffect and other hooks? Without this, we need to re-render twice with the same state in this example to ensure that the counter's state is consistent.

As a comparison, a Component with render props would have no problems with reseting the state when necessary: https://codesandbox.io/s/3vrpnxo2kq

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

React Version: 16.7.0-alpha.2-next

@gaearon
Copy link
Collaborator

gaearon commented Nov 20, 2018

getDerivedStateFromProps is generally discouraged because it hides bugs (just like componentWillReceiveProps). We wrote a detailed blog post explaining why that is the case. Generally we'd prefer not to emphasize this pattern.

You can, however, implement something similar, by using setState during rendering, as mentioned in the FAQ. Here is an example of how you can do it: https://codesandbox.io/s/vv85v4j53.

Hope this helps!

@gaearon gaearon closed this as completed Nov 20, 2018
@peterjuras
Copy link
Author

Thanks I missed that part in the FAQ! What happens to the first render output? What should libraries with custom hooks return for the first useless render? Or is rendering stopped immediately?

@gaearon
Copy link
Collaborator

gaearon commented Nov 20, 2018

What happens to the first render output?

It's ignored so it doesn't matter in practice. React won't re-render deeply. It will immediately call the render again.

@peterjuras
Copy link
Author

Also, just out of curiosity: What speaks against the second argument to useState, similar to the other hooks?

@gaearon
Copy link
Collaborator

gaearon commented Nov 20, 2018

Hmm. I dunno. It seems a bit niche but I kinda like it?
Can you file an RFC please? https://github.com/reactjs/rfcs

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

No branches or pull requests

2 participants