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

Replay capture phase for continuous events #22680

Closed

Conversation

salazarm
Copy link
Contributor

@salazarm salazarm commented Nov 2, 2021

Summary

We want to replay the capture phase for continuous events on hydration (currently we only replay the bubble phase).

This will allow us to call stopPropagation() in the capture phase to prevent the bubble phase.

With this change we also use the browsers native event dispatching to replay events. This allows stopPropagation in the capture phase to actually stop the bubble phase from firing without needing to hook into the native event / simulating the capture / bubble phase in a single phase.

Quirks:

  • Enter/Leave event emulation runs in the bubble phase of mouseout (normally) and mouseover(replay). (existing behavior)
  • This means that calling stopPropagation during the capture phase of mouseout would normally prevent mouseenter/mouseleave listeners from firing (Codesandbox showing this existing behavior: https://codesandbox.io/s/silly-microservice-n3vv1?file=/src/App.js) but since before this PR we didn't replay the capture phase there was no way to stop it during replaying.
  • Now that we replay the capture phase, calling stopPropagation during the capture phase of mouseover would prevent mouseenter (Replay uses mouseover to emulate mouseEnter because we don't replay mouseout events, perhaps we could replay them in a special way for replay where we actually ignore them from simpleEventPlugin if they're being replayed).
  • mouseout is never replayed so mouseleave is also never replayed (existing behavior)

I included these changes under the existing enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay so that I don't need a new experiment and since we want to enable all of these changes together

How did you test this change?

jest

@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Nov 2, 2021
@salazarm salazarm force-pushed the replayCapturePhaseContinuousEvents branch from 04d2106 to fb47c18 Compare November 2, 2021 17:52
@sizebot
Copy link

sizebot commented Nov 2, 2021

Comparing: 4ff5f57...bfe8062

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.22% 129.98 kB 130.26 kB +0.33% 41.56 kB 41.70 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js +0.21% 134.74 kB 135.02 kB +0.29% 42.96 kB 43.08 kB
facebook-www/ReactDOM-prod.classic.js +0.71% 424.31 kB 427.31 kB +0.58% 78.20 kB 78.65 kB
facebook-www/ReactDOM-prod.modern.js +0.73% 412.87 kB 415.86 kB +0.58% 76.47 kB 76.91 kB
facebook-www/ReactDOMForked-prod.classic.js +0.71% 424.31 kB 427.31 kB +0.58% 78.20 kB 78.65 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
facebook-www/ReactDOM-prod.modern.js +0.73% 412.87 kB 415.86 kB +0.58% 76.47 kB 76.91 kB
facebook-www/ReactDOMForked-prod.modern.js +0.73% 412.87 kB 415.86 kB +0.58% 76.47 kB 76.91 kB
facebook-www/ReactDOM-prod.classic.js +0.71% 424.31 kB 427.31 kB +0.58% 78.20 kB 78.65 kB
facebook-www/ReactDOMForked-prod.classic.js +0.71% 424.31 kB 427.31 kB +0.58% 78.20 kB 78.65 kB
facebook-www/ReactDOM-profiling.modern.js +0.67% 444.70 kB 447.69 kB +0.53% 81.88 kB 82.31 kB
facebook-www/ReactDOMForked-profiling.modern.js +0.67% 444.70 kB 447.69 kB +0.53% 81.88 kB 82.32 kB
facebook-www/ReactDOM-profiling.classic.js +0.66% 456.20 kB 459.20 kB +0.53% 83.65 kB 84.10 kB
facebook-www/ReactDOMForked-profiling.classic.js +0.66% 456.20 kB 459.20 kB +0.53% 83.65 kB 84.10 kB
facebook-www/ReactDOMTesting-prod.classic.js +0.36% 420.10 kB 421.62 kB +0.40% 78.91 kB 79.23 kB
facebook-www/ReactDOMTesting-prod.modern.js +0.36% 406.78 kB 408.24 kB +0.36% 76.74 kB 77.02 kB
facebook-www/ReactDOMForked-dev.modern.js +0.36% 1,095.58 kB 1,099.48 kB +0.20% 243.07 kB 243.55 kB
facebook-www/ReactDOM-dev.modern.js +0.36% 1,095.58 kB 1,099.48 kB +0.20% 243.07 kB 243.55 kB
facebook-www/ReactDOMForked-dev.classic.js +0.35% 1,119.70 kB 1,123.61 kB +0.11% 248.08 kB 248.35 kB
facebook-www/ReactDOM-dev.classic.js +0.35% 1,119.70 kB 1,123.61 kB +0.11% 248.08 kB 248.35 kB
oss-stable-semver/react-dom/cjs/react-dom.production.min.js +0.22% 129.98 kB 130.26 kB +0.33% 41.56 kB 41.70 kB
oss-stable/react-dom/cjs/react-dom.production.min.js +0.22% 129.98 kB 130.26 kB +0.33% 41.56 kB 41.70 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js +0.21% 134.74 kB 135.02 kB +0.29% 42.96 kB 43.08 kB
oss-stable-semver/react-dom/umd/react-dom.production.min.js +0.21% 130.12 kB 130.39 kB +0.25% 42.29 kB 42.40 kB
oss-stable/react-dom/umd/react-dom.production.min.js +0.21% 130.12 kB 130.39 kB +0.25% 42.29 kB 42.40 kB
oss-stable-semver/react-dom/cjs/react-dom.profiling.min.js +0.20% 139.56 kB 139.84 kB +0.25% 44.43 kB 44.54 kB
oss-stable/react-dom/cjs/react-dom.profiling.min.js +0.20% 139.56 kB 139.84 kB +0.25% 44.43 kB 44.54 kB
oss-experimental/react-dom/umd/react-dom.production.min.js +0.20% 134.79 kB 135.07 kB +0.31% 43.61 kB 43.75 kB

Generated by 🚫 dangerJS against bfe8062

@salazarm salazarm changed the title Replay capture phase for continuous events [draft] Replay capture phase for continuous events Nov 2, 2021
@salazarm salazarm force-pushed the replayCapturePhaseContinuousEvents branch from 4f77598 to e7cc04d Compare November 3, 2021 17:11
@salazarm salazarm changed the title [draft] Replay capture phase for continuous events Replay capture phase for continuous events Nov 3, 2021
@salazarm salazarm force-pushed the replayCapturePhaseContinuousEvents branch from 8a7e8c8 to 236af6c Compare November 8, 2021 16:53
@salazarm salazarm force-pushed the replayCapturePhaseContinuousEvents branch from 6e5bdcb to 6bf50cb Compare November 17, 2021 17:36
}
} else {
// This tree has been unmounted already. Dispatch without a target.
return nullTarget;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I couldn't come up with a test case where we findInstanceBlockingEvent would return nullTarget. It doesn't seem possible that it would ever happen because it would mean that there is a React Instance defined on the target but then nearestMountedFiber returns null for this case. I added a test which attempted to simulate this by removing the target node from its react tree into a tree where there is no react root but that didn't seem to work.

getClosestInstanceFromNode(getEventTarget(queuedEvent.nativeEvent)) did return null for this case though.

Based off how hydration works it shouldn't be possible for the nearestMountedFiber to ever be anything other than a SuspenseInstance. Unless the node is manually moved in userland to a different tree thats already hydrated, I tried doing that but that also didn't trigger the nullTarget. I'm unsure what else to try to trigger it. Any ideas?

@salazarm salazarm force-pushed the replayCapturePhaseContinuousEvents branch from 83a3868 to ea448a4 Compare November 30, 2021 21:26
@salazarm salazarm force-pushed the replayCapturePhaseContinuousEvents branch from ea448a4 to a88e173 Compare December 1, 2021 14:04
@gaearon
Copy link
Collaborator

gaearon commented Dec 2, 2021

Merged via #22856.

@gaearon gaearon closed this Dec 2, 2021
@salazarm salazarm deleted the replayCapturePhaseContinuousEvents branch February 10, 2022 14:27
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.

4 participants