Do you want to request a feature or report a bug?
Bug
What is the current behavior?
Using the State hook, calling setXYZ() with the same value multiple times causes the component function to be evaluated more than once (up-to 2 times). I don't mean re-rendered, but a re-evaluation of its function.
Scenario 1 (OK):
useState(1)setState(1)setState(1)setState(1)Scenario 2:
useState(1)setState(2)setState(2)setState(2)setState(2)If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:
https://jsfiddle.net/qf103zvj/
What is the expected behavior?
Just as Scenario 1, I'd expect ONLY one re-evaluation of the component function.
Scenario 2:
useState(1)setState(2)setState(2)setState(2)Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
Chrome 78, Firefox 70, React 16; Both macOS, Linux. Unsure about previous versions of React.
Interesting discovery. This certainly doesn't look like a useful feature.
This is a known quirk due to the implementation details of concurrency in React. We don't cheaply know which of two versions is currently committed. When this ambiguity happens we have to over render once and after that we know that both versions are the same and it doesn't matter.
I encountered the same thing while trying to understand React hooks better.
Check out this fiddle, and open up the Console tab. https://jsfiddle.net/devotis/jd12g7y4/
In that fiddle, the App function is run one extra time after calling setValue with the same value, but the result of the last function call, is not being sent to the dom. Also notice how useEffect is not calling its function after that last function call (which makes sense, because there wasn't any effect in the dom with that last function call).
I do not consider this a bug. Just something I didn't expect at the time. To be precise; I didn't expect the App function to be called the last time (when setValue was called with the same value). The explanation by @sebmarkbage makes sense though. Is this behaviour documented somewhere?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution.
Most helpful comment
This is a known quirk due to the implementation details of concurrency in React. We don't cheaply know which of two versions is currently committed. When this ambiguity happens we have to over render once and after that we know that both versions are the same and it doesn't matter.