Skip to content

Commit f655b67

Browse files
committed
Add simulateEventDispatch to test ReactDOMEventListener (#28079)
## Overview For events, the browser will yield to microtasks between calling event handers, allowing time to flush work inbetween. For example, in the browser, this code will log the flushes between events: ```js <body onclick="console.log('body'); Promise.resolve().then(() => console.log('flush body'));"> <div onclick="console.log('div'); Promise.resolve().then(() => console.log('flush div'));"> hi </div> </body> // Logs div flush div body flush body ``` [Sandbox](https://codesandbox.io/s/eloquent-noether-mw2cjg?file=/index.html) The problem is, `dispatchEvent` (either in the browser, or JSDOM) does not yield to microtasks. Which means, this code will log the flushes after the events: ```js const target = document.getElementsByTagName("div")[0]; const nativeEvent = document.createEvent("Event"); nativeEvent.initEvent("click", true, true); target.dispatchEvent(nativeEvent); // Logs div body flush div flush body ``` ## The problem This mostly isn't a problem because React attaches event handler at the root, and calls the event handlers on components via the synthetic event system. We handle flushing between calling event handlers as needed. However, if you're mixing capture and bubbling events, or using multiple roots, then the problem of not flushing microtasks between events can come into play. This was found when converting a test to `createRoot` in #28050 (comment), and that test is an example of where this is an issue with nested roots. Here's a sandox for [discrete](https://codesandbox.io/p/sandbox/red-http-2wg8k5) and [continuous](https://codesandbox.io/p/sandbox/gracious-voice-6r7tsc?file=%2Fsrc%2Findex.js%3A25%2C28) events, showing how the test should behave. The existing test, when switched to `createRoot` matches the browser behavior for continuous events, but not discrete. Continuous events should be batched, and discrete should flush individually. ## The fix This PR implements the fix suggested by @sebmarkbage, to manually traverse the path up from the element and dispatch events, yielding between each call. DiffTrain build for commit cd63ef7.
1 parent ce4b2c2 commit f655b67

File tree

7 files changed

+9
-9
lines changed

7 files changed

+9
-9
lines changed

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25670,7 +25670,7 @@ if (__DEV__) {
2567025670
return root;
2567125671
}
2567225672

25673-
var ReactVersion = "18.3.0-canary-04b59928d-20240208";
25673+
var ReactVersion = "18.3.0-canary-cd63ef792-20240208";
2567425674

2567525675
// Might add PROFILE later.
2567625676

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9152,7 +9152,7 @@ var devToolsConfig$jscomp$inline_1011 = {
91529152
throw Error("TestRenderer does not support findFiberByHostInstance()");
91539153
},
91549154
bundleType: 0,
9155-
version: "18.3.0-canary-04b59928d-20240208",
9155+
version: "18.3.0-canary-cd63ef792-20240208",
91569156
rendererPackageName: "react-test-renderer"
91579157
};
91589158
var internals$jscomp$inline_1189 = {
@@ -9183,7 +9183,7 @@ var internals$jscomp$inline_1189 = {
91839183
scheduleRoot: null,
91849184
setRefreshHandler: null,
91859185
getCurrentFiber: null,
9186-
reconcilerVersion: "18.3.0-canary-04b59928d-20240208"
9186+
reconcilerVersion: "18.3.0-canary-cd63ef792-20240208"
91879187
};
91889188
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
91899189
var hook$jscomp$inline_1190 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9580,7 +9580,7 @@ var devToolsConfig$jscomp$inline_1053 = {
95809580
throw Error("TestRenderer does not support findFiberByHostInstance()");
95819581
},
95829582
bundleType: 0,
9583-
version: "18.3.0-canary-04b59928d-20240208",
9583+
version: "18.3.0-canary-cd63ef792-20240208",
95849584
rendererPackageName: "react-test-renderer"
95859585
};
95869586
var internals$jscomp$inline_1230 = {
@@ -9611,7 +9611,7 @@ var internals$jscomp$inline_1230 = {
96119611
scheduleRoot: null,
96129612
setRefreshHandler: null,
96139613
getCurrentFiber: null,
9614-
reconcilerVersion: "18.3.0-canary-04b59928d-20240208"
9614+
reconcilerVersion: "18.3.0-canary-cd63ef792-20240208"
96159615
};
96169616
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
96179617
var hook$jscomp$inline_1231 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ if (__DEV__) {
2424
) {
2525
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
2626
}
27-
var ReactVersion = "18.3.0-canary-04b59928d-20240208";
27+
var ReactVersion = "18.3.0-canary-cd63ef792-20240208";
2828

2929
// ATTENTION
3030
// When adding new symbols to this file,

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,4 +543,4 @@ exports.useSyncExternalStore = function (
543543
exports.useTransition = function () {
544544
return ReactCurrentDispatcher.current.useTransition();
545545
};
546-
exports.version = "18.3.0-canary-04b59928d-20240208";
546+
exports.version = "18.3.0-canary-cd63ef792-20240208";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ exports.useSyncExternalStore = function (
539539
exports.useTransition = function () {
540540
return ReactCurrentDispatcher.current.useTransition();
541541
};
542-
exports.version = "18.3.0-canary-04b59928d-20240208";
542+
exports.version = "18.3.0-canary-cd63ef792-20240208";
543543
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
544544
"function" ===
545545
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
04b59928d867dae1639f12f19700347d8f5d4cac
1+
cd63ef79218a1d53c8739da75b154014f3b7cc73

0 commit comments

Comments
 (0)