-
Notifications
You must be signed in to change notification settings - Fork 48.6k
Double invoke effects in a subtree wrapped with StrictMode
#32315
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
Double invoke effects in a subtree wrapped with StrictMode
#32315
Conversation
Comparing: ff62833...89afbaa Critical size changesIncludes critical production bundles, as well as any change greater than 2%:
Significant size changesIncludes any change greater than 0.2%: (No significant changes) |
@@ -4079,16 +4079,20 @@ function flushRenderPhaseStrictModeWarningsInDEV() { | |||
function recursivelyTraverseAndDoubleInvokeEffectsInDEV( | |||
root: FiberRoot, | |||
parentFiber: Fiber, | |||
treeFlags: Flags, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The problem is that in this scenario only the root gets
PlacementDev
flag becausereconcileChildren
routes tomountChildFibers
for all of the descendant's fibers. - That in turn is a reconciler function created with
shouldTrackSideEffects === false
- So
.subtreeFlags
can't be relied upon because, well, those flags are not set on those descendant fibers so they are also not propagated onto their ancestors'.subtreeFlags
That led me to propagate the treeFlags
through the callers' chain here
82ee1ee
to
5af49d5
Compare
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Thanks for the PR @Andarist, I looked into this a bit and React 19 has the expected behavior. It's not safe for So this is considered a bugfix for React 19. I have a PR to add a note explaining the difference. In the future, when we land the Activity API, we plan to double invoke effect on mount within |
Summary
Currently, strict effects don't behave as expected when
StrictMode
isn't placed at the root of the app. Wrapping only a part of the app is a valid use case described in the docs: https://react.dev/reference/react/StrictMode#enabling-strict-mode-for-a-part-of-the-appHow did you test this change?
I added tests in the repo to verify that it works 😉
I expect some subtleties around this so this might not be a fully correct PR (yet). With some guidance I could improve it. I'm especially not sure if the code paths related to Offscree/Visibility are changed correctly. If you could suggest some extra test cases for them, I'd appreciate it