Description
Do you want to request a feature or report a bug? Bug
What is the current behavior?
When wrapping a with React.StrictMode
, setState
is fired twice
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:
Here is the jsFiddle
By clicking on a title and checking the console, you should see that the setState
is called twice (its callback, however, is called only once).
What is the expected behavior?
Not sure, it might be related to #12094, then the behaviour might be intended. But when using the previous state to set the new one, then the component breaks if setState
is fired twice (for instance, toggle components don't work).
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React 16.3
Activity
nmain commentedon May 18, 2018
The
prevState => nextState
callback is fired twice, but I don't see the behavior you're talking about with toggle components not working. If you add some more logging or rendering to your example, you'll see that the toggle in it does in fact work correctly:https://jsfiddle.net/oq58bf9k/
gaearon commentedon May 18, 2018
It is expected that setState updaters will run twice in strict mode in development. This helps ensure the code doesn't rely on them running a single time (which wouldn't be the case if an async render was aborted and alter restarted). If your setState updaters are pure functions (as they should be) then this shouldn't affect the logic of your application.
franklixuefei commentedon May 31, 2018
@gaearon Consider this example
say this piece of code will be triggered by clicking on a button. If
setState
updater function can be called multiple times underStrictMode
, then how do I guarantee that mycounter
only increments by 1 per click?Actually, this is a real example in my project, where I have a button, and
setState
was triggered after I clicked on the button. I noticed that the updater function in mysetState
was called twice, resulting in inconsistency.aweary commentedon May 31, 2018
@franklixuefei the updater should be called twice with the same state. For example, if
counter
is 0 it will be called with 0 twice, returning 1 in both cases.Also I believe only one of the invocations actually cares about the value returned. So React isn't processing each state update twice, it's just calling the function twice to help surface issues related to side effects in a state updater and other methods that should be pure.
franklixuefei commentedon May 31, 2018
@aweary Thanks for answering my question! However, this is not the case. Take a look at the below real-life example from my project:
where
selectedItems
is just an array of objects. I noticed that in this example, the updater function was called twice (can be seen from the console log), and the second time the updater function was called,selectedItems
contains one fewer element than the first time. Trust me, I was banging my head on this bug last night...iamdustan commentedon May 31, 2018
splice
mutates the array so this looks like the type of impurity that strict mode is intended to catch 😄franklixuefei commentedon May 31, 2018
@iamdustan I noticed that too, but if you look closely, I created a new array at the end:
Oh wait... You are right! It modified the original array even though I returned a new array!
I'm so surprised that I didn't even think of it at first. What a shame.
Now I realized how great
React.StrictMode
is.Thanks @iamdustan and @aweary
kumar303 commentedon Sep 26, 2018
Similarly,
constructor()
is called twice with the same props. If you're dispatching a loading action that triggers API fetching and more action dispatching via something like saga then it makes development pretty confusing. You might see flashes of UI changes as the component enters its loading state multiple times.I'm not sure how helpful this is for day to day development. I guess it's just a downside to relying on side effects with Saga?
tonix-tuft commentedon Aug 3, 2019
I am experiencing the same "issue" (
setState
updater function called twice) even if I do not useReact.StrictMode
(I am using React 16.8.6). Is this behaviour enabled by default on React 16.8.6?34 remaining items