-
Notifications
You must be signed in to change notification settings - Fork 1.3k
fix: React 19 strict mode drag and drop bug #8562
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
Conversation
@@ -240,9 +241,11 @@ export function useDrag(options: DragOptions): DragResult { | |||
// If the dragged element is removed from the DOM via onDrop, onDragEnd won't fire: https://bugzilla.mozilla.org/show_bug.cgi?id=460801 | |||
// In this case, we need to manually call onDragEnd on cleanup | |||
|
|||
useLayoutEffect(() => { | |||
useEffect(() => { |
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.
Switched to useEffect because layout effect cleanups happen before the element is actually removed.
looks like a react 16 test is failing though |
Build successful! 🎉 |
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.
Not able to reproduce the original issue
Closes #8548
Due to facebook/react#29585, React sometimes triggers extra effect cleanups when elements are reordered. This can occur during virtualized scrolling. When keyboard dragging and scrolling the dragged element out of view, the drop target would unexpectedly shift to another target. The layout effect caused the drag to be aborted and the global state to reset, resulting in our
isInternal
checks failing.This stores the actual dragged element in a ref instead of just a boolean. Then in the effect cleanup we check if the element has actually unmounted from the DOM. This will ignore false positives caused by strict mode where React calls the cleanup function even when not actually unmounting.