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

[Experimental] Add useInsertionEffect #21913

Merged
merged 1 commit into from
Sep 14, 2021

Conversation

rickhanlonii
Copy link
Member

@rickhanlonii rickhanlonii commented Jul 19, 2021

Overview

Adds back the experimental useMutationEffect hook as useInsertionEffect, initially intended for stylesheet libraries.

Semantics

This hook is called right before mutations are made to the host, to allow inserting dependencies of the soon-to-be mutated host nodes. The canonical example use case is for inserting styles into the DOM so that they're available before reading layout information from DOM nodes that they apply to (like reading height in useLayoutEffect). Since this hook is limited in scope, this hook does not have access to refs and cannot schedule updates.

The lifecycle of this hook is a little different than other hooks. useInsertionEffect will interleave create and destroy while traversing the tree in the beforeMutation phase. This means that as we traverse the tree before mutations (e.g. the same time we call getSnapshotBeforeUpdate), and for each component we will destroy all of the insertion effects and then create all of the insertion effects for that component.

The resulting in ordering is something like:

Destroy Insertion 1 for Component A
Destroy Insertion 2 for Component A
Create Insertion 1 for Component A
Create Insertion 2 for Component A
Destroy Insertion 1 for Component B
Destroy Insertion 2 for Component B
Create Insertion 1 for Component B
Create Insertion 2 for Component B

Contrast this with layout effects, which do a two passes. One to destroy all of the layout effects in every component, and a second to create them:

Destroy Layout 1 for Component A
Destroy Layout 2 for Component A
Destroy Layout 1 for Component B
Destroy Layout 2 for Component B
Create Layout 1 for Component A
Create Layout 2 for Component A
Create Layout 1 for Component B
Create Layout 2 for Component B

@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Jul 19, 2021
@sizebot
Copy link

sizebot commented Jul 19, 2021

Comparing: 81db4eb...ab6ad9f

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.min.js +0.15% 128.27 kB 128.46 kB +0.09% 40.93 kB 40.96 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js +0.15% 131.09 kB 131.29 kB +0.11% 41.85 kB 41.90 kB
facebook-www/ReactDOM-prod.classic.js +0.13% 407.09 kB 407.60 kB +0.07% 75.40 kB 75.46 kB
facebook-www/ReactDOM-prod.modern.js +0.13% 395.65 kB 396.17 kB +0.07% 73.69 kB 73.75 kB
facebook-www/ReactDOMForked-prod.classic.js +0.13% 407.09 kB 407.60 kB +0.07% 75.40 kB 75.46 kB
oss-experimental/react-debug-tools/cjs/react-debug-tools.production.min.js +2.01% 6.76 kB 6.90 kB +0.66% 2.59 kB 2.61 kB
oss-stable-semver/react-debug-tools/cjs/react-debug-tools.production.min.js +2.01% 6.76 kB 6.90 kB +0.66% 2.59 kB 2.61 kB
oss-stable/react-debug-tools/cjs/react-debug-tools.production.min.js +2.01% 6.76 kB 6.90 kB +0.66% 2.59 kB 2.61 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-experimental/react-debug-tools/cjs/react-debug-tools.production.min.js +2.01% 6.76 kB 6.90 kB +0.66% 2.59 kB 2.61 kB
oss-stable-semver/react-debug-tools/cjs/react-debug-tools.production.min.js +2.01% 6.76 kB 6.90 kB +0.66% 2.59 kB 2.61 kB
oss-stable/react-debug-tools/cjs/react-debug-tools.production.min.js +2.01% 6.76 kB 6.90 kB +0.66% 2.59 kB 2.61 kB
oss-experimental/react-suspense-test-utils/cjs/react-suspense-test-utils.js +1.42% 2.61 kB 2.65 kB +0.82% 1.10 kB 1.10 kB
oss-stable-semver/react-suspense-test-utils/cjs/react-suspense-test-utils.js +1.42% 2.61 kB 2.65 kB +0.82% 1.10 kB 1.10 kB
oss-stable/react-suspense-test-utils/cjs/react-suspense-test-utils.js +1.42% 2.61 kB 2.65 kB +0.82% 1.10 kB 1.10 kB
oss-experimental/react/cjs/react.production.min.js +1.19% 7.73 kB 7.83 kB +0.54% 2.97 kB 2.98 kB
oss-experimental/react-debug-tools/cjs/react-debug-tools.development.js +1.13% 23.16 kB 23.43 kB +0.47% 6.17 kB 6.20 kB
oss-stable-semver/react-debug-tools/cjs/react-debug-tools.development.js +1.13% 23.16 kB 23.43 kB +0.47% 6.17 kB 6.20 kB
oss-stable/react-debug-tools/cjs/react-debug-tools.development.js +1.13% 23.16 kB 23.43 kB +0.47% 6.17 kB 6.20 kB
facebook-react-native/react/cjs/React-prod.js +0.82% 17.04 kB 17.18 kB +0.28% 4.36 kB 4.37 kB
facebook-react-native/react/cjs/React-profiling.js +0.82% 17.04 kB 17.18 kB +0.28% 4.36 kB 4.37 kB
facebook-www/React-prod.modern.js +0.82% 17.17 kB 17.31 kB +0.25% 4.40 kB 4.41 kB
facebook-www/React-profiling.modern.js +0.82% 17.17 kB 17.31 kB +0.25% 4.40 kB 4.41 kB
facebook-www/React-prod.classic.js +0.81% 17.31 kB 17.45 kB +0.27% 4.44 kB 4.46 kB
facebook-www/React-profiling.classic.js +0.81% 17.31 kB 17.45 kB +0.27% 4.44 kB 4.46 kB
oss-experimental/react/umd/react.profiling.min.js +0.73% 11.73 kB 11.82 kB +0.13% 4.62 kB 4.63 kB
oss-experimental/react/umd/react.production.min.js +0.73% 11.73 kB 11.82 kB +0.13% 4.62 kB 4.63 kB
facebook-www/ReactDOMServer-dev.classic.js +0.36% 152.43 kB 152.97 kB +0.09% 38.80 kB 38.84 kB
facebook-react-native/react-test-renderer/cjs/ReactTestRenderer-dev.js +0.34% 614.81 kB 616.90 kB +0.14% 132.95 kB 133.14 kB
oss-stable-semver/react-test-renderer/umd/react-test-renderer.development.js +0.34% 633.66 kB 635.78 kB +0.12% 133.33 kB 133.49 kB
oss-stable/react-test-renderer/umd/react-test-renderer.development.js +0.34% 633.66 kB 635.78 kB +0.12% 133.33 kB 133.49 kB
facebook-www/ReactTestRenderer-dev.classic.js +0.33% 626.23 kB 628.32 kB +0.14% 134.16 kB 134.35 kB
facebook-www/ReactTestRenderer-dev.modern.js +0.33% 626.24 kB 628.34 kB +0.14% 134.17 kB 134.36 kB
oss-stable-semver/react-test-renderer/cjs/react-test-renderer.development.js +0.33% 604.16 kB 606.18 kB +0.13% 131.95 kB 132.13 kB
oss-stable/react-test-renderer/cjs/react-test-renderer.development.js +0.33% 604.16 kB 606.18 kB +0.13% 131.95 kB 132.13 kB
oss-experimental/react-test-renderer/umd/react-test-renderer.development.js +0.33% 650.35 kB 652.48 kB +0.11% 136.73 kB 136.88 kB
oss-experimental/react-test-renderer/cjs/react-test-renderer.development.js +0.33% 620.01 kB 622.02 kB +0.12% 135.31 kB 135.47 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-writer.browser.production.min.server.js +0.32% 6.63 kB 6.65 kB +0.25% 2.81 kB 2.82 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-writer.browser.production.min.server.js +0.32% 6.63 kB 6.65 kB +0.25% 2.81 kB 2.82 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-writer.browser.production.min.server.js +0.32% 6.63 kB 6.65 kB +0.25% 2.81 kB 2.82 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-writer.node.production.min.server.js +0.32% 6.64 kB 6.66 kB +0.29% 2.79 kB 2.79 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-writer.node.production.min.server.js +0.32% 6.64 kB 6.66 kB +0.29% 2.79 kB 2.79 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-writer.node.production.min.server.js +0.32% 6.64 kB 6.66 kB +0.29% 2.79 kB 2.79 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler.development.js +0.31% 705.16 kB 707.34 kB +0.14% 149.86 kB 150.07 kB
oss-stable/react-reconciler/cjs/react-reconciler.development.js +0.31% 705.16 kB 707.34 kB +0.14% 149.86 kB 150.07 kB
oss-stable-semver/react-art/cjs/react-art.development.js +0.31% 654.00 kB 656.02 kB +0.13% 141.71 kB 141.89 kB
oss-stable/react-art/cjs/react-art.development.js +0.31% 654.00 kB 656.02 kB +0.13% 141.71 kB 141.89 kB
oss-experimental/react-server/cjs/react-server-flight.production.min.js +0.31% 6.81 kB 6.83 kB +0.31% 2.86 kB 2.87 kB
oss-stable-semver/react-server/cjs/react-server-flight.production.min.js +0.31% 6.81 kB 6.83 kB +0.31% 2.86 kB 2.87 kB
oss-stable/react-server/cjs/react-server-flight.production.min.js +0.31% 6.81 kB 6.83 kB +0.31% 2.86 kB 2.87 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-writer.browser.production.min.server.js +0.31% 6.84 kB 6.86 kB +0.28% 2.90 kB 2.91 kB
oss-stable-semver/react-server-dom-webpack/umd/react-server-dom-webpack-writer.browser.production.min.server.js +0.31% 6.84 kB 6.86 kB +0.28% 2.90 kB 2.91 kB
oss-stable/react-server-dom-webpack/umd/react-server-dom-webpack-writer.browser.production.min.server.js +0.31% 6.84 kB 6.86 kB +0.28% 2.90 kB 2.91 kB
oss-experimental/react-reconciler/cjs/react-reconciler.development.js +0.30% 721.23 kB 723.41 kB +0.12% 153.30 kB 153.49 kB
oss-experimental/react-art/cjs/react-art.development.js +0.30% 669.88 kB 671.90 kB +0.12% 145.09 kB 145.26 kB
react-native/implementations/ReactFabric-dev.js +0.30% 705.56 kB 707.66 kB +0.13% 152.81 kB 153.00 kB
facebook-www/ReactART-dev.modern.js +0.30% 707.86 kB 709.95 kB +0.11% 151.10 kB 151.27 kB
facebook-www/ReactART-dev.classic.js +0.29% 718.14 kB 720.23 kB +0.11% 153.20 kB 153.38 kB
react-native/implementations/ReactNativeRenderer-dev.js +0.29% 722.70 kB 724.80 kB +0.12% 156.74 kB 156.93 kB
react-native/implementations/ReactFabric-dev.fb.js +0.29% 727.55 kB 729.65 kB +0.13% 157.16 kB 157.37 kB
react-native/implementations/ReactNativeRenderer-dev.fb.js +0.28% 742.68 kB 744.78 kB +0.12% 160.55 kB 160.73 kB
oss-stable-semver/react-art/umd/react-art.development.js +0.28% 757.41 kB 759.53 kB +0.10% 160.04 kB 160.21 kB
oss-stable/react-art/umd/react-art.development.js +0.28% 757.41 kB 759.53 kB +0.10% 160.04 kB 160.21 kB
oss-experimental/react-art/umd/react-art.development.js +0.27% 774.13 kB 776.25 kB +0.10% 163.47 kB 163.63 kB
facebook-www/ReactFlightDOMRelayServer-prod.classic.js +0.26% 15.51 kB 15.55 kB +0.23% 3.96 kB 3.97 kB
facebook-www/ReactFlightDOMRelayServer-prod.modern.js +0.26% 15.51 kB 15.55 kB +0.23% 3.96 kB 3.97 kB
facebook-relay/flight/ReactFlightNativeRelayServer-prod.js +0.26% 15.92 kB 15.96 kB +0.22% 4.05 kB 4.06 kB
oss-stable-semver/react-test-renderer/cjs/react-test-renderer.production.min.js +0.25% 78.23 kB 78.43 kB +0.21% 24.24 kB 24.29 kB
oss-stable/react-test-renderer/cjs/react-test-renderer.production.min.js +0.25% 78.23 kB 78.43 kB +0.21% 24.24 kB 24.29 kB
oss-stable-semver/react-test-renderer/umd/react-test-renderer.production.min.js +0.24% 78.45 kB 78.64 kB +0.22% 24.62 kB 24.67 kB
oss-stable/react-test-renderer/umd/react-test-renderer.production.min.js +0.24% 78.45 kB 78.64 kB +0.22% 24.62 kB 24.67 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler.production.min.js +0.24% 90.45 kB 90.67 kB +0.21% 27.78 kB 27.84 kB
oss-stable/react-reconciler/cjs/react-reconciler.production.min.js +0.24% 90.45 kB 90.67 kB +0.21% 27.78 kB 27.84 kB
oss-experimental/react-test-renderer/cjs/react-test-renderer.production.min.js +0.24% 80.61 kB 80.81 kB +0.18% 25.01 kB 25.05 kB
oss-experimental/react-test-renderer/umd/react-test-renderer.production.min.js +0.24% 80.82 kB 81.01 kB +0.21% 25.39 kB 25.44 kB
oss-stable-semver/react-art/cjs/react-art.production.min.js +0.24% 81.37 kB 81.56 kB +0.16% 25.26 kB 25.30 kB
oss-stable/react-art/cjs/react-art.production.min.js +0.24% 81.37 kB 81.56 kB +0.16% 25.26 kB 25.30 kB
oss-experimental/react-reconciler/cjs/react-reconciler.production.min.js +0.24% 92.90 kB 93.12 kB +0.20% 28.55 kB 28.60 kB
oss-experimental/react/cjs/react.development.js +0.23% 85.12 kB 85.32 kB +0.13% 22.72 kB 22.75 kB
oss-experimental/react-art/cjs/react-art.production.min.js +0.23% 83.76 kB 83.95 kB +0.11% 26.04 kB 26.07 kB
facebook-react-native/react-test-renderer/cjs/ReactTestRenderer-prod.js +0.22% 234.60 kB 235.13 kB +0.15% 43.06 kB 43.12 kB
facebook-www/ReactDOMTesting-dev.modern.js +0.22% 946.24 kB 948.33 kB +0.09% 212.89 kB 213.09 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler.profiling.min.js +0.22% 98.22 kB 98.44 kB +0.14% 30.11 kB 30.15 kB
oss-stable/react-reconciler/cjs/react-reconciler.profiling.min.js +0.22% 98.22 kB 98.44 kB +0.14% 30.11 kB 30.15 kB
oss-experimental/react-reconciler/cjs/react-reconciler.profiling.min.js +0.22% 100.69 kB 100.90 kB +0.16% 30.87 kB 30.92 kB
facebook-www/ReactDOMTesting-dev.classic.js +0.22% 973.31 kB 975.40 kB +0.09% 218.53 kB 218.73 kB
oss-stable-semver/react-dom/umd/react-dom.development.js +0.21% 1,020.73 kB 1,022.86 kB +0.07% 221.23 kB 221.39 kB
oss-stable/react-dom/umd/react-dom.development.js +0.21% 1,020.73 kB 1,022.86 kB +0.07% 221.23 kB 221.39 kB
oss-stable-semver/react-dom/cjs/react-dom.development.js +0.21% 971.53 kB 973.55 kB +0.09% 218.60 kB 218.78 kB
oss-stable/react-dom/cjs/react-dom.development.js +0.21% 971.53 kB 973.55 kB +0.09% 218.60 kB 218.78 kB
react-native/implementations/ReactFabric-prod.js +0.21% 270.91 kB 271.47 kB +0.13% 48.74 kB 48.80 kB
oss-experimental/react-dom/umd/react-dom.development.js +0.20% 1,039.54 kB 1,041.66 kB +0.07% 224.94 kB 225.10 kB
oss-experimental/react-dom/cjs/react-dom.development.js +0.20% 989.37 kB 991.39 kB +0.07% 222.35 kB 222.52 kB
facebook-www/ReactART-prod.modern.js +0.20% 256.30 kB 256.82 kB +0.14% 45.87 kB 45.94 kB
react-native/implementations/ReactFabric-prod.fb.js +0.20% 278.21 kB 278.77 kB +0.12% 50.06 kB 50.12 kB
facebook-www/ReactDOMForked-dev.modern.js +0.20% 1,044.17 kB 1,046.26 kB +0.08% 231.88 kB 232.06 kB
facebook-www/ReactDOM-dev.modern.js +0.20% 1,044.17 kB 1,046.26 kB +0.08% 231.88 kB 232.06 kB

Generated by 🚫 dangerJS against ab6ad9f

@gaearon
Copy link
Collaborator

gaearon commented Jul 19, 2021

The old version used effect lists, so this version includes a naive, and probably buggy implementation using the new effect traversals.

I’d say effect lists were the usual cause of bugs so you have a higher chance of doing it right with the current approach!

@rickhanlonii rickhanlonii force-pushed the rh-usemutationeffect branch 9 times, most recently from a10210c to c6ceff6 Compare July 20, 2021 03:54
Copy link
Collaborator

@acdlite acdlite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall! Let's discuss the timing of the destroy function before merging

@rickhanlonii rickhanlonii self-assigned this Aug 24, 2021
@windmaomao
Copy link

@rickhanlonii just curious is the point of having this hook is to handle something even earlier than LayoutEffect? do you have a common use case to use it? Thank you.

@rickhanlonii rickhanlonii changed the title [Experimental] Add back useMutationEffect [Experimental] Add useInsertionEffect Sep 10, 2021
@rickhanlonii
Copy link
Member Author

@windmaomao I updated the description with the use case 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants