Skip to content
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

Merged
merged 5 commits into from
Aug 22, 2019

Conversation

sebmarkbage
Copy link
Collaborator

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.

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);
Copy link
Collaborator Author

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.

@sizebot
Copy link

sizebot commented Aug 21, 2019

ReactDOM: size: 0.0%, gzip: 0.0%

Details of bundled changes.

Comparing: efa5dbe...93bc6cb

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js +0.1% +0.2% 649.76 KB 650.53 KB 141.82 KB 142.04 KB UMD_DEV
react-art.production.min.js 0.0% -0.0% 101.82 KB 101.84 KB 31.12 KB 31.12 KB UMD_PROD
react-art.development.js +0.1% +0.2% 580.63 KB 581.4 KB 124.43 KB 124.65 KB NODE_DEV
react-art.production.min.js 0.0% 🔺+0.1% 66.83 KB 66.85 KB 20.36 KB 20.38 KB NODE_PROD
ReactART-dev.js +0.1% +0.2% 595.92 KB 596.68 KB 124.19 KB 124.45 KB FB_WWW_DEV
ReactART-prod.js -0.0% -0.0% 221.41 KB 221.4 KB 37.73 KB 37.72 KB FB_WWW_PROD

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.profiling.min.js 0.0% +0.1% 115.18 KB 115.23 KB 36.31 KB 36.33 KB NODE_PROFILING
ReactDOM-dev.js +0.1% +0.1% 933.25 KB 934.01 KB 206.46 KB 206.73 KB FB_WWW_DEV
react-dom-server.browser.production.min.js 0.0% 0.0% 19.74 KB 19.74 KB 7.34 KB 7.34 KB UMD_PROD
react-dom-test-utils.development.js 0.0% +0.3% 57.19 KB 57.22 KB 15.73 KB 15.78 KB UMD_DEV
react-dom-unstable-fizz.browser.development.js 0.0% +0.1% 3.78 KB 3.78 KB 1.53 KB 1.53 KB UMD_DEV
react-dom-test-utils.production.min.js -0.2% 🔺+0.1% 11.2 KB 11.18 KB 4.15 KB 4.15 KB UMD_PROD
react-dom-unstable-fizz.browser.production.min.js 0.0% 🔺+0.3% 1.2 KB 1.2 KB 700 B 702 B UMD_PROD
react-dom-test-utils.development.js 0.0% +0.3% 55.47 KB 55.49 KB 15.4 KB 15.45 KB NODE_DEV
react-dom-unstable-fizz.browser.development.js 0.0% +0.1% 3.61 KB 3.61 KB 1.48 KB 1.48 KB NODE_DEV
react-dom-test-utils.production.min.js -0.2% 🔺+0.3% 10.98 KB 10.95 KB 4.08 KB 4.09 KB NODE_PROD
react-dom-unstable-fizz.browser.production.min.js 0.0% 🔺+0.3% 1.04 KB 1.04 KB 631 B 633 B NODE_PROD
react-dom.development.js +0.1% +0.1% 908.85 KB 909.62 KB 206.33 KB 206.6 KB UMD_DEV
react-dom.production.min.js 0.0% 🔺+0.1% 111.58 KB 111.62 KB 35.99 KB 36 KB UMD_PROD
ReactTestUtils-dev.js +0.1% +0.3% 52.7 KB 52.73 KB 14.09 KB 14.13 KB FB_WWW_DEV
react-dom.profiling.min.js 0.0% +0.1% 114.98 KB 115.03 KB 37 KB 37.04 KB UMD_PROFILING
react-dom.development.js +0.1% +0.1% 903.14 KB 903.91 KB 204.72 KB 204.98 KB NODE_DEV
react-dom-server.node.development.js 0.0% -0.0% 138.05 KB 138.05 KB 36.24 KB 36.24 KB NODE_DEV
react-dom.production.min.js 0.0% 🔺+0.1% 111.54 KB 111.6 KB 35.39 KB 35.41 KB NODE_PROD
ReactDOM-prod.js 0.0% 🔺+0.1% 369.51 KB 369.6 KB 67.78 KB 67.83 KB FB_WWW_PROD
ReactDOM-profiling.js 0.0% +0.1% 374.71 KB 374.8 KB 68.82 KB 68.87 KB FB_WWW_PROFILING
react-dom-unstable-native-dependencies.development.js 0.0% 0.0% 60.71 KB 60.71 KB 15.84 KB 15.85 KB UMD_DEV
react-dom-unstable-native-dependencies.production.min.js 0.0% 🔺+0.1% 10.75 KB 10.75 KB 3.67 KB 3.68 KB UMD_PROD
ReactDOMServer-dev.js 0.0% 0.0% 141.34 KB 141.34 KB 35.59 KB 35.6 KB FB_WWW_DEV
ReactDOMServer-prod.js 0.0% 0.0% 48.13 KB 48.13 KB 11.05 KB 11.05 KB FB_WWW_PROD
react-dom-unstable-native-dependencies.development.js 0.0% 0.0% 60.39 KB 60.39 KB 15.72 KB 15.72 KB NODE_DEV
react-dom-unstable-fizz.node.development.js 0.0% +0.2% 3.87 KB 3.87 KB 1.51 KB 1.51 KB NODE_DEV
react-dom-unstable-native-dependencies.production.min.js 0.0% 🔺+0.1% 10.49 KB 10.49 KB 3.57 KB 3.58 KB NODE_PROD
react-dom-unstable-fizz.node.production.min.js 0.0% 🔺+0.3% 1.1 KB 1.1 KB 665 B 667 B NODE_PROD

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactTestRenderer-dev.js +0.1% +0.2% 606.95 KB 607.71 KB 126.6 KB 126.85 KB FB_WWW_DEV
react-test-renderer-shallow.development.js 0.0% 0.0% 39.01 KB 39.01 KB 9.9 KB 9.9 KB UMD_DEV
react-test-renderer-shallow.production.min.js 0.0% 🔺+0.1% 11.41 KB 11.41 KB 3.53 KB 3.53 KB UMD_PROD
react-test-renderer-shallow.development.js 0.0% 0.0% 33.18 KB 33.18 KB 8.49 KB 8.49 KB NODE_DEV
react-test-renderer-shallow.production.min.js 0.0% 🔺+0.1% 11.55 KB 11.55 KB 3.62 KB 3.62 KB NODE_PROD
react-test-renderer.development.js +0.1% +0.2% 593.74 KB 594.51 KB 127.13 KB 127.36 KB UMD_DEV
react-test-renderer.production.min.js 0.0% 0.0% 68.77 KB 68.79 KB 21.15 KB 21.15 KB UMD_PROD
react-test-renderer.development.js +0.1% +0.2% 589.27 KB 590.05 KB 125.98 KB 126.21 KB NODE_DEV
react-test-renderer.production.min.js 0.0% 🔺+0.1% 68.46 KB 68.48 KB 20.86 KB 20.88 KB NODE_PROD

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js +0.1% +0.2% 579.25 KB 580.02 KB 123.09 KB 123.32 KB NODE_DEV
react-reconciler.production.min.js 🔺+0.1% 🔺+0.1% 68.8 KB 68.85 KB 20.41 KB 20.42 KB NODE_PROD
react-reconciler-reflection.development.js +0.1% +0.7% 19.19 KB 19.21 KB 6.28 KB 6.32 KB NODE_DEV
react-reconciler-reflection.production.min.js -0.9% 🔺+0.9% 2.58 KB 2.56 KB 1.13 KB 1.14 KB NODE_PROD
react-reconciler-persistent.development.js +0.1% +0.2% 576.28 KB 577.06 KB 121.84 KB 122.07 KB NODE_DEV
react-reconciler-persistent.production.min.js 🔺+0.1% 🔺+0.1% 68.81 KB 68.86 KB 20.42 KB 20.43 KB NODE_PROD

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-prod.js 🔺+0.1% 🔺+0.1% 269.59 KB 269.73 KB 46.21 KB 46.25 KB RN_OSS_PROD
ReactNativeRenderer-profiling.js +0.1% 0.0% 278.05 KB 278.19 KB 47.75 KB 47.77 KB RN_OSS_PROFILING
ReactFabric-prod.js 0.0% 0.0% 261.44 KB 261.46 KB 44.91 KB 44.92 KB RN_OSS_PROD
ReactFabric-profiling.js +0.1% 0.0% 270.11 KB 270.25 KB 46.42 KB 46.44 KB RN_OSS_PROFILING
ReactFabric-dev.js +0.1% +0.2% 735.13 KB 735.89 KB 155.62 KB 155.87 KB RN_FB_DEV
ReactFabric-prod.js 0.0% 0.0% 261.45 KB 261.46 KB 44.92 KB 44.94 KB RN_FB_PROD
ReactNativeRenderer-dev.js +0.1% +0.2% 728.58 KB 729.34 KB 154.46 KB 154.7 KB RN_OSS_DEV
ReactFabric-profiling.js +0.1% 0.0% 270.11 KB 270.25 KB 46.43 KB 46.45 KB RN_FB_PROFILING
ReactNativeRenderer-dev.js +0.1% +0.2% 728.74 KB 729.5 KB 154.53 KB 154.79 KB RN_FB_DEV
ReactNativeRenderer-prod.js 🔺+0.1% 🔺+0.1% 269.59 KB 269.73 KB 46.22 KB 46.26 KB RN_FB_PROD
ReactNativeRenderer-profiling.js +0.1% 0.0% 278.04 KB 278.18 KB 47.76 KB 47.77 KB RN_FB_PROFILING
ReactFabric-dev.js +0.1% +0.2% 734.96 KB 735.73 KB 155.55 KB 155.79 KB RN_OSS_DEV

Generated by 🚫 dangerJS

@trueadm
Copy link
Contributor

trueadm commented Aug 21, 2019

Please can you add a test for the new event system? You could add a test in DOMEventResponderSystem-test.internal. Notably, event responders mount during complete phase, so this will likely have to move to the commit phase now:

https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberCompleteWork.js#L693-L774

@sebmarkbage
Copy link
Collaborator Author

@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

@trueadm
Copy link
Contributor

trueadm commented Aug 21, 2019

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?

@sebmarkbage
Copy link
Collaborator Author

sebmarkbage commented Aug 21, 2019

@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 dispatchEvent which is great.)

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

@trueadm
Copy link
Contributor

trueadm commented Aug 21, 2019

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants