-
Notifications
You must be signed in to change notification settings - Fork 47.5k
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
React.StrictMode combined with useState causes component to render twice #15074
Comments
It's an intentional feature of the StrictMode. This only happens in development, and helps find accidental side effects put into the render phase. We only do this for components with Hooks because those are more likely to accidentally have side effects in the wrong place. |
Sorry, I know this was closed, but you say
but if your component uses a class -- even if it's stateless -- it also renders twice. Threw me for a loop today trying to figure out why my component wasn't working properly.
|
Strict Mode always did this for classes. That’s the first thing it ever did. :-) The question was about function components. So I explained that for function components, this was only on when they contained Hooks. In any case, we’ve changed that too already so it will fire for all function components soon. |
If I'm understanding the documentation correctly, the purpose of this is to bring the developer's attention to lifestate function that are non-idempotent, because these might cause problems when concurrent mode is rolled out. So, I'm assuming just ignoring double renders that cause double sideeffects in StrictMode is not a good idea for future proofing.
Nevermind, I had a brain fart. It's a non-issue; both times the function is called in this double render, it is called with the same initial state, so appending again and returning will return the same result. |
I know this one is closed, but I don't want to open a new ticket just for this. The first click will be triggered once, but subsequent clicks will add duplicate items. |
Hey @nermand (I think) the trouble you're seeing is because The use of Notice that |
Cheers @jaredkhan, that explains it. |
Hi, I understand the motivation for this. However, I really don't know how to approach a problem I have with debouncing an event handler. Here's a simplified version of my current code: function ExampleComponent () {
const [debouncedHandlerFn] = useState(() => debounce(handlerFn, 1000))
return <div onSomeEvent={debouncedHandlerFn} />
} What I'm trying to achieve here is to handle an event in a debounced manner. The I'm using lazy state initialization because it is the only way to put a function in the component state (it is also more efficient as it is not creating debounced versions of the function on every render). What I expect is to have a unique debounced function instance per mounted component. This does work in production, but strict mode is rendering my component twice and executing the lazy-loading function twice. Actually I haven't checked if it still works fine (I guess it should, as it would retain the last instance, I'm gonna check now), but it doesn't seem like a clean way to go about this. Any thoughts? Thanks :) |
Nevermind, I got it. Figured out this is not a problem as long as the debounced function is being called from an event handler, as it will be called at later later after the second render is done, so no side-effects here. |
🙆♂️ Dan's answer explained my confusion |
facebook/react#15074 🔥 StrictMode가 실행되어 Hook을 사용하는 컴포넌트가 2번 렌더링 되는 문제를 해당 코드를 삭제함으로써 해결했습니다.
In my project, I integrate SSR in which the server delivers data to client to be used in the first render. To save memory, I want to clear the data after the first render (and also prevent the data from being re-used). Because I have 2 questions. I really appreciate if anyone can help me figure it out
Thank you very much. |
Can you clean it in the effect? |
Awesome. Thank you for opening my mind. I did not think about it.
Thank you very much. Edit: I have made it. No more warning, re-fetching. |
This comment has been minimized.
This comment has been minimized.
Ohh. Why didn't you mark this in the documentation for StrictMode? |
I am updating the parent state count inside the array from children but strict mode updates the state twice. For example :
I want to increase the count and invert the active state but the following code
with strict mode causes the count to increase by 2 Any way to fix this issue? |
The
|
thanks, mate works fine 🚀 |
Now, with the new My data fetching library works as follows:
The However, in react 18, Currently, I have a workaround by increasing the I would like to raise my usecase here to ask if you have any advice on this. Or is |
Can you post a minimal runnable code example? |
It is hard to mimic the hydration behavior with client-only code, I tried my best to reproduce the error here: https://codesandbox.io/s/react-18-strict-mode-with-subscription-pattern-zfrfss?file=%2Fsrc%2FApp.js Note about the demo: the error is actually different in the real SSR app (my app). In my app (real SSR), error is However, the behaviors are the same. Error in client-only SSR-mimic demo. Test 1data is empty, the server sends HTML with empty data immediately and the client fetches the data itself. const LazyChild = lazy(async () => {
await sleep(1000)
return {default: ConsumeData}
})
const App = () => <>
<ConsumeData/>
<Suspense>
<LazyChild/>
</Suspense>
</> Step 1: App is rendered, LazyChild is suspended Test 2:data is fully resolved in server, and populated to the store in the client before the hydration starts. StrictMode causes hydration mismatch. const App = () => <StrictMode>
<ConsumeData/>
<Suspense>
<ConsumeData/>
</Suspense>
</StrictMode> Step 1: data is populated to the store In test 2, if Suspense OR StrictMode is removed from the tree, no error will occur. |
Please file a new one so we can track it? This issue is from 2019 and is about a different topic. I haven't looked closely but I think you're probably misusing Suspense. Suspense is not meant to be managed by external store + effects. It's meant to be used with a separate cache that uses a different architecture. But regardless, a separate issue to discuss would be best. |
Do you want to request a feature or report a bug?
Bug (maybe)
What is the current behavior?
If wrapped in React.StrictMode and a function component contains a call to
useState
, the function (render) is called twice - even if the state setter is never called.If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.
https://codesandbox.io/s/lyw9514j4q
(please see console)
What is the expected behavior?
I would expect it to only render once.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
16.8.3 in Chrome on macOS Mojave; requires hooks so not tested with previous versions.
This may be related to #12961 - but note that nowhere am I setting state (only initializing it).
If this is expected behavior please feel free to close. Thank you!
The text was updated successfully, but these errors were encountered: