8000 Add dispatchEvent to fragment instances by jackpope · Pull Request #32813 · facebook/react · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add dispatchEvent to fragment instances #32813

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

Merged
merged 3 commits into from
May 7, 2025

Conversation

jackpope
Copy link
Contributor
@jackpope jackpope commented Apr 3, 2025

fragmentInstance.dispatchEvent(evt) calls element.dispatchEvent(evt) on the fragment's host parent. This mimics bubbling if the fragmentInstance could receive an event itself.

If the parent is disconnected, there is a dev warning and no event is dispatched.

@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label Apr 3, 2025
@react-sizebot
Copy link
react-sizebot commented Apr 3, 2025

Comparing: e5a8de8...30f04c2

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.68 kB 6.68 kB +0.05% 1.83 kB 1.83 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 528.26 kB 528.26 kB = 93.16 kB 93.16 kB
oss-experimental/react-dom/cjs/reac 8000 t-dom.production.js = 6.69 kB 6.69 kB +0.11% 1.83 kB 1.83 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js +0.19% 645.02 kB 646.24 kB +0.18% 113.47 kB 113.67 kB
facebook-www/ReactDOM-prod.classic.js +0.18% 673.72 kB 674.94 kB +0.17% 118.32 kB 118.52 kB
facebook-www/ReactDOM-prod.modern.js +0.18% 664.00 kB 665.22 kB +0.15% 116.73 kB 116.91 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
facebook-react-native/react-dom/cjs/ReactDOMClient-prod.js +0.21% 574.83 kB 576.04 kB +0.17% 101.25 kB 101.42 kB
facebook-react-native/react-dom/cjs/ReactDOMProfiling-prod.js +0.21% 580.33 kB 581.55 kB +0.17% 102.34 kB 102.51 kB
facebook-react-native/react-dom/cjs/ReactDOMClient-profiling.js +0.20% 603.02 kB 604.24 kB +0.17% 105.29 kB 105.46 kB

Generated by 🚫 dangerJS against 30f04c2

console.error(
'You are attempting to dispatch an event on a disconnected ' +
'FragmentInstance. No event was dispatched.',
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if this is necessary. It might backfire if you don't know, now you have to check with something like getRootNode() instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah probably more annoying than anything. Updated for it to just exit silently.

}
return true;
}
return parentHostInstance.dispatchEvent(event);
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's interesting because we have addEventListener on the ref. Shouldn't those listeners be invoked too? It's kind of weird that your own listeners wouldn't fire.

We could manually invoke them but unfortunately the timing wouldn't be quite right in the capture/bubble phase.

One simple thing we can do is:

Suggested change
return parentHostInstance.dispatchEvent(event);
if (this.__eventListeners !== null || !event.bubbles) {
const temp = document.createTextNode('')
// addEventListener for all the ones in __eventListeners
parentHostInstance.appendChild(temp);
return temp.dispatchEvent(event);
parentHostInstance.removeChild(temp);
} else {
return parentHostInstance.dispatchEvent(event);
}

Most of the times the simple path is hit because you're unlike to both listen and dispatch to the same event type and even more unlikely to have non-bubbling dispatches.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also felt like it was a bit awkward but wasn't sure about the right semantics. This feels reasonable to me, updated to include this logic.

@@ -2331,6 +2332,23 @@ function removeEventListenerFromChild(
return false;
}
// $FlowFixMe[prop-missing]
FragmentInstance.prototype.dispatchEvent = function (
this: FragmentInstanceType,
event: Event,
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should check if this event.bubbles is true because if it's false, it should only fire on the fragment's own listeners and no the parent node. This can be solved by the same technique as self listeners.

Copy link
Contributor
@jbrown215 jbrown215 left a comment

Choose a reason for hiding this comment

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

@jackpope and I discussed this together. The way I interpreted this diff is as "event propagation for fragment refs" and we discussed making sure that if one of the fragment ref handles calls event.stopPropagation that this would work under this implementation

@jackpope jackpope merged commit 8a8df5d into facebook:main May 7, 2025
239 checks passed
@jackpope jackpope deleted the fragment-refs-events branch May 7, 2025 18:01
github-actions bot pushed a commit that referenced this pull request May 7, 2025
`fragmentInstance.dispatchEvent(evt)` calls `element.dispatchEvent(evt)`
on the fragment's host parent. This mimics bubbling if the
`fragmentInstance` could receive an event itself.

If the parent is disconnected, there is a dev warning and no event is
dispatched.

DiffTrain build for [8a8df5d](8a8df5d)
github-actions bot pushed a commit that referenced this pull request May 7, 2025
`fragmentInstance.dispatchEvent(evt)` calls `element.dispatchEvent(evt)`
on the fragment's host parent. This mimics bubbling if the
`fragmentInstance` could receive an event itself.

If the parent is disconnected, there is a dev warning and no event is
dispatched.

DiffTrain build for [8a8df5d](8a8df5d)
github-actions bot pushed a commit to code/lib-react that referenced this pull request May 7, 2025
`fragmentInstance.dispatchEvent(evt)` calls `element.dispatchEvent(evt)`
on the fragment's host parent. This mimics bubbling if the
`fragmentInstance` could receive an event itself.

If the parent is disconnected, there is a dev warning and no event is
dispatched.

DiffTrain build for [8a8df5d](facebook@8a8df5d)
github-actions bot pushed a commit to code/lib-react that referenced this pull request May 7, 2025
`fragmentInstance.dispatchEvent(evt)` calls `element.dispatchEvent(evt)`
on the fragment's host parent. This mimics bubbling if the
`fragmentInstance` could receive an event itself.

If the parent is disconnected, there is a dev warning and no event is
dispatched.

DiffTrain build for [8a8df5d](facebook@8a8df5d)
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.

5 participants
0