-
Notifications
You must be signed in to change notification settings - Fork 47.3k
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
[Partial Hydration] Dispatching events should not work until hydration commits #16532
[Partial Hydration] Dispatching events should not work until hydration commits #16532
Conversation
This is equivalent to a "Placement" effect in that it's a new insertion to the tree but it doesn't need an actual mutation. It is only used to determine if a subtree has actually mounted yet.
Previous roots had a Placement flag on them as a hack for this case but since we have a special flag for it now, we can just use that.
|
||
// We're now partially hydrated. | ||
a.click(); | ||
expect(clicks).toBe(0); |
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.
This is the thing that this PR fixes. It used to let these through.
ReactDOM: size: 0.0%, gzip: 0.0% Details of bundled changes.Comparing: efa5dbe...93bc6cb react-art
react-dom
react-test-renderer
react-reconciler
react-native-renderer
Generated by 🚫 dangerJS |
Please can you add a test for the new event system? You could add a test in |
@trueadm That seems like a bigger issue we need to deal with. Particularly, this is not concurrent mode safe: https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberCompleteWork.js#L1346-L1347 |
That code was designed to work like the existing model for assigning props against the DOM instance, which is also done in the complete phase. I’m happy to change it, but it’s based on previous feedback that I guess no longer holds with concurrent mode? |
@trueadm It assigned against the DOM in the complete phase for initial mount (when there is no current). That normally work since you can't fire an event on something that doesn't exist in the DOM yet (except for hydration). That's the same thing that this PR is dealing with. That part is legit, so I'll add a test for the same thing for Flare. (I believe it should just work since Flare goes through the same mechanism in However, for updates to an already mounted DOM component we do it in the commit phase since the old listeners remain valid until we're ready to commit. https://github.com/facebook/react/blob/master/packages/react-dom/src/client/ReactDOMHostConfig.js#L371 |
Seems like those two lines you highlighted need to be moved to the commit phase then and then it should work as expected. I can do that tomorrow :) |
This includes a bunch of clean up to set up for selective hydration.
Primarily the bug it fixes is that we attach event listeners while hydrating but these need to be noops (and later replayable) until we actually commit. Since the parent may not be mounted any setStates that we let through might become invalid.
There's no way around that we need some commit-phase effect to indicate when it's done. We could do these on all event listeners but it's sufficient to just do it at the root of the things we're hydrating.
In fact, we did that with HostRoot already by attaching a fake Placement effect tag on it.
This PR formalizes that by making Hydrating a new effect tag. It means that this is the beginning of a in-progress hydrating subtree. The tag gets removed in the commit phase to indicate that the tree is mounted. Same as Placement.