Skip to content

Conversation

@sebmarkbage
Copy link
Collaborator

useInsertionEffect is meant to be used to insert <style> tags that affect the layout. It allows precomputing a layout before it mounts.

Since we're not normally firing any effects during the "apply gesture" phase where we create the clones, it's possible for the target snapshot to be missing styles. This makes it so that useInsertionEffect for a new tree are mounted before the snapshot is taken and then unmounted before the animation starts.

Note that because we are mounting a clone of the DOM tree and the previous DOM tree remains mounted during the snapshot, we can't unmount any previous insertion effects. This can lead to conflicts but that is similar to what can happen with conflicts for two mounted Activity boundaries since insertion effects can remain mounted inside those.

A revealed Activity will have already had their insertion effects fired while offscreen.

However, one thing this doesn't yet do is handle the case where a useInsertionEffect is updated as part of a gesture being applied. This means it's still possible for it to miss some styles in that case. The interesting thing there is that since the old state and the new state will both be applicable to the global DOM in this phase, what should really happen is that we should mount the new updated state without unmounting the old state and then unmount the updated state. Meaning you can have the same hook in the mounted state twice at the same time.

This only applies to newly inserted Fibers and not clones (e.g. if they
were cloned from a previous offscreen tree which would've inserted them
already).
This restores things before starting the actual animation whose target
snapshot should represent the current state that's mounted.
@meta-cla meta-cla bot added the CLA Signed label Jan 19, 2026
@sebmarkbage sebmarkbage changed the title Temporarily Mount useInsertionEffect while a snapshot is being computed Temporarily Mount useInsertionEffect while a Gesture snapshot is being computed Jan 19, 2026
@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label Jan 19, 2026
@react-sizebot
Copy link

react-sizebot commented Jan 19, 2026

Comparing: 41b3e9a...ffaae72

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.js = 6.84 kB 6.84 kB = 1.88 kB 1.88 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 608.48 kB 608.48 kB = 107.60 kB 107.60 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB = 1.88 kB 1.88 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js +0.13% 670.95 kB 671.79 kB +0.14% 118.02 kB 118.18 kB
facebook-www/ReactDOM-prod.classic.js = 693.87 kB 693.87 kB = 121.97 kB 121.97 kB
facebook-www/ReactDOM-prod.modern.js = 684.25 kB 684.25 kB = 120.37 kB 120.37 kB
oss-experimental/react-server/cjs/react-server.development.js = 214.39 kB 209.99 kB = 37.90 kB 37.10 kB
oss-stable-semver/react-server/cjs/react-server.development.js = 209.60 kB 205.20 kB = 36.97 kB 36.17 kB
oss-stable/react-server/cjs/react-server.development.js = 209.60 kB 205.20 kB = 36.97 kB 36.17 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-markup/cjs/react-markup.react-server.development.js = 672.86 kB 668.57 kB = 119.15 kB 118.34 kB
oss-experimental/react-dom/cjs/react-dom-server.node.development.js = 460.87 kB 456.48 kB = 80.35 kB 79.49 kB
oss-experimental/react-dom/cjs/react-dom-server.edge.development.js = 455.11 kB 450.72 kB = 80.59 kB 79.73 kB
oss-experimental/react-dom/cjs/react-dom-server.browser.development.js = 454.11 kB 449.71 kB = 80.36 kB 79.50 kB
oss-stable/react-dom/cjs/react-dom-server.node.development.js = 444.86 kB 440.47 kB = 78.09 kB 77.21 kB
oss-stable-semver/react-dom/cjs/react-dom-server.node.development.js = 444.79 kB 440.39 kB = 78.04 kB 77.16 kB
oss-experimental/react-dom/cjs/react-dom-server.bun.development.js = 402.04 kB 398.06 kB = 75.91 kB 75.07 kB
oss-stable/react-dom/cjs/react-dom-server.edge.development.js = 438.60 kB 434.21 kB = 78.29 kB 77.41 kB
oss-stable-semver/react-dom/cjs/react-dom-server.edge.development.js = 438.53 kB 434.13 kB = 78.24 kB 77.37 kB
oss-stable/react-dom/cjs/react-dom-server.browser.development.js = 437.82 kB 433.43 kB = 78.10 kB 77.24 kB
oss-stable-semver/react-dom/cjs/react-dom-server.browser.development.js = 437.75 kB 433.35 kB = 78.05 kB 77.20 kB
oss-stable/react-dom/cjs/react-dom-server.bun.development.js = 387.88 kB 383.90 kB = 73.59 kB 72.78 kB
oss-stable-semver/react-dom/cjs/react-dom-server.bun.development.js = 387.81 kB 383.83 kB = 73.56 kB 72.76 kB
oss-experimental/react-dom/cjs/react-dom-server-legacy.browser.development.js = 423.72 kB 419.33 kB = 76.15 kB 75.32 kB
oss-experimental/react-dom/cjs/react-dom-server-legacy.node.development.js = 423.72 kB 419.32 kB = 76.15 kB 75.32 kB
facebook-www/ReactDOMServer-dev.classic.js = 422.74 kB 418.34 kB = 75.89 kB 75.05 kB
facebook-www/ReactDOMServer-dev.modern.js = 419.30 kB 414.90 kB = 75.29 kB 74.45 kB
facebook-www/ReactDOMServerStreaming-dev.modern.js = 417.81 kB 413.41 kB = 74.83 kB 74.02 kB
oss-stable/react-dom/cjs/react-dom-server-legacy.browser.development.js = 408.43 kB 404.03 kB = 73.92 kB 73.09 kB
oss-stable/react-dom/cjs/react-dom-server-legacy.node.development.js = 408.43 kB 404.03 kB = 73.93 kB 73.10 kB
oss-stable-semver/react-dom/cjs/react-dom-server-legacy.browser.development.js = 408.40 kB 404.01 kB = 73.90 kB 73.07 kB
oss-stable-semver/react-dom/cjs/react-dom-server-legacy.node.development.js = 408.40 kB 404.01 kB = 73.90 kB 73.07 kB
oss-experimental/react-markup/cjs/react-markup.development.js = 395.45 kB 391.18 kB = 71.81 kB 71.05 kB
oss-experimental/react-server/cjs/react-server.development.js = 214.39 kB 209.99 kB = 37.90 kB 37.10 kB
oss-stable-semver/react-server/cjs/react-server.development.js = 209.60 kB 205.20 kB = 36.97 kB 36.17 kB
oss-stable/react-server/cjs/react-server.development.js = 209.60 kB 205.20 kB = 36.97 kB 36.17 kB

Generated by 🚫 dangerJS against ffaae72

@sebmarkbage sebmarkbage force-pushed the gestureinsertioneffect branch from 77cc9eb to ffaae72 Compare January 19, 2026 22:59
@sebmarkbage sebmarkbage merged commit 1ecd99c into facebook:main Jan 20, 2026
234 checks passed
github-actions bot pushed a commit that referenced this pull request Jan 20, 2026
…g computed (#35565)

`useInsertionEffect` is meant to be used to insert `<style>` tags that
affect the layout. It allows precomputing a layout before it mounts.

Since we're not normally firing any effects during the "apply gesture"
phase where we create the clones, it's possible for the target snapshot
to be missing styles. This makes it so that `useInsertionEffect` for a
new tree are mounted before the snapshot is taken and then unmounted
before the animation starts.

Note that because we are mounting a clone of the DOM tree and the
previous DOM tree remains mounted during the snapshot, we can't unmount
any previous insertion effects. This can lead to conflicts but that is
similar to what can happen with conflicts for two mounted Activity
boundaries since insertion effects can remain mounted inside those.

A revealed Activity will have already had their insertion effects fired
while offscreen.

However, one thing this doesn't yet do is handle the case where a
`useInsertionEffect` is *updated* as part of a gesture being applied.
This means it's still possible for it to miss some styles in that case.
The interesting thing there is that since the old state and the new
state will both be applicable to the global DOM in this phase, what
should really happen is that we should mount the new updated state
without unmounting the old state and then unmount the updated state.
Meaning you can have the same hook in the mounted state twice at the
same time.

DiffTrain build for [1ecd99c](1ecd99c)
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.

3 participants