-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
DevTools: useModalDismissSignal bugfix #21173
Conversation
Make useModalDismissSignal's manually added click/keyboard events more robust to sync flushed passive effects. (Don't let the same click event that shows a modal dialog also dismiss it.)
Comparing: b4f119c...8f1087e Critical size changesIncludes critical production bundles, as well as any change greater than 2%:
Significant size changesIncludes any change greater than 0.2%: (No significant changes) |
Hmm. It’s not obvious to me that relying on a timestamp is the correct solution. What happens if some code in the middle just happens to spend enough CPU time? Does this affect the logic anyhow? |
@gaearon I'm not sure I understand the scenario you're describing. The specific issue I'm fixing here is tis:
So my fix is to check if the click event was trigger before the passive effect that added the listener. This fix should not be affected by code running in the middle. (That would just make the delta between the event and effect time larger.) An alternative fix would be to add a small delay before attaching my event handler in the effect, but this approach seemed more obvious/direct. |
Do we expect any problems due to limited precision? Eg Firefox seems to have a privacy setting for this. https://developer.mozilla.org/en-US/docs/Web/API/Event/timeStamp |
Even for older implementations, I don't think it seems that likely for React to render an update, commit it, and flush passive effects in < 1 ms. And because I return only if I also don't think it's very common for React DevTools to be running in older browser versions. For instance, Chrome switched to high res timestamps in version 49 (released over 5 years ago). Seems likely that people using DevTools would also be using versions of Chrome released more recently than 5 years ago. |
This comment has been minimized.
This comment has been minimized.
As mentioned in the comment above yours, I don't think this concern seems too likely. 😄
Simply delaying the event listener with Something like this should be fine though: useEffect(() => {
function handler(event) {
// ...
}
let timeoutID = setTimeout(() => {
timeoutID = null;
window.addEventListener("click", handler);
}, 0);
return () => {
if (timeoutID !== null) {
clearTimeout(timeoutID);
}
window.removeEventListener("click", handler);
};
}); I think I slightly prefer the timeout approach in this PR though because the intent seems clearer to me. |
Yes, we're actually doing that. Just was a bit lazy with my comment. |
I'm still tempted to try this fix because I prefer the clarity of it vs the timestamp and I don't think it's problematic (especially in the DevTools case) but if we're concerned about setting a highly visible precedent for this case that may be copied elsewhere, I won't choose to die on this hill. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it would be good to discuss with the team what's the canonical fix for this. Like you said, it's not so much about this case but just what do we actually recommend other people do.
Sounds good. Added it to our sync topics. |
Btw, @eps1lon, I took the time to write up my thoughts/preferences about this at a little more length. In case you're interested: https://gist.github.com/bvaughn/fc1c3f27f1aab91c7378f2264f7c3aa1 |
* DevTools: useModalDismissSignal bugfix Make useModalDismissSignal's manually added click/keyboard events more robust to sync flushed passive effects. (Don't let the same click event that shows a modal dialog also dismiss it.) * Replaced event.timeStamp check with setTimeout
* DevTools: useModalDismissSignal bugfix Make useModalDismissSignal's manually added click/keyboard events more robust to sync flushed passive effects. (Don't let the same click event that shows a modal dialog also dismiss it.) * Replaced event.timeStamp check with setTimeout
* DevTools: useModalDismissSignal bugfix Make useModalDismissSignal's manually added click/keyboard events more robust to sync flushed passive effects. (Don't let the same click event that shows a modal dialog also dismiss it.) * Replaced event.timeStamp check with setTimeout
* DevTools: useModalDismissSignal bugfix Make useModalDismissSignal's manually added click/keyboard events more robust to sync flushed passive effects. (Don't let the same click event that shows a modal dialog also dismiss it.) * Replaced event.timeStamp check with setTimeout
* DevTools: useModalDismissSignal bugfix Make useModalDismissSignal's manually added click/keyboard events more robust to sync flushed passive effects. (Don't let the same click event that shows a modal dialog also dismiss it.) * Replaced event.timeStamp check with setTimeout
This test is failing for the same reason as facebook/react#21173, so we'll borrow their fix, and follow along for updates.
* DevTools: useModalDismissSignal bugfix Make useModalDismissSignal's manually added click/keyboard events more robust to sync flushed passive effects. (Don't let the same click event that shows a modal dialog also dismiss it.) * Replaced event.timeStamp check with setTimeout
Make useModalDismissSignal's manually added click/keyboard events more robust to sync flushed passive effects. (Don't let the same click event that shows a modal dialog also dismiss it.)
Fixes #21172