Skip to content

Commit ce66903

Browse files
matthewreiterrolandjitsu
authored andcommitted
fix: store drag targets in a ref and close react-dropzone#876 (react-dropzone#877)
This avoids unnecessary renders when drag targets change, which works around an issue where the drag targets get cleared out by the browser when dragging into a child element of the drop zone.
1 parent 536997c commit ce66903

File tree

1 file changed

+12
-15
lines changed

1 file changed

+12
-15
lines changed

src/index.js

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import React, {
66
useEffect,
77
useMemo,
88
useReducer,
9-
useRef,
10-
useState
9+
useRef
1110
} from 'react'
1211
import PropTypes from 'prop-types'
1312
import { fromEvent } from 'file-selector'
@@ -469,14 +468,14 @@ export function useDropzone({
469468
}
470469
}, [inputRef, noClick])
471470

472-
const [dragTargets, setDragTargets] = useState([])
471+
const dragTargetsRef = useRef([])
473472
const onDocumentDrop = event => {
474473
if (rootRef.current && rootRef.current.contains(event.target)) {
475474
// If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler
476475
return
477476
}
478477
event.preventDefault()
479-
setDragTargets([])
478+
dragTargetsRef.current = []
480479
}
481480

482481
useEffect(() => {
@@ -501,8 +500,8 @@ export function useDropzone({
501500
stopPropagation(event)
502501

503502
// Count the dropzone and any children that are entered.
504-
if (dragTargets.indexOf(event.target) === -1) {
505-
setDragTargets([...dragTargets, event.target])
503+
if (dragTargetsRef.current.indexOf(event.target) === -1) {
504+
dragTargetsRef.current = [...dragTargetsRef.current, event.target]
506505
}
507506

508507
if (isEvtWithFiles(event)) {
@@ -523,7 +522,7 @@ export function useDropzone({
523522
})
524523
}
525524
},
526-
[dragTargets, getFilesFromEvent, onDragEnter, noDragEventsBubbling]
525+
[getFilesFromEvent, onDragEnter, noDragEventsBubbling]
527526
)
528527

529528
const onDragOverCb = useCallback(
@@ -554,12 +553,10 @@ export function useDropzone({
554553
stopPropagation(event)
555554

556555
// Only deactivate once the dropzone and all children have been left
557-
const targets = [
558-
...dragTargets.filter(
559-
target => target !== event.target && rootRef.current && rootRef.current.contains(target)
560-
)
561-
]
562-
setDragTargets(targets)
556+
const targets = dragTargetsRef.current.filter(
557+
target => target !== event.target && rootRef.current && rootRef.current.contains(target)
558+
)
559+
dragTargetsRef.current = targets
563560
if (targets.length > 0) {
564561
return
565562
}
@@ -574,7 +571,7 @@ export function useDropzone({
574571
onDragLeave(event)
575572
}
576573
},
577-
[rootRef, dragTargets, onDragLeave, noDragEventsBubbling]
574+
[rootRef, onDragLeave, noDragEventsBubbling]
578575
)
579576

580577
const onDropCb = useCallback(
@@ -584,7 +581,7 @@ export function useDropzone({
584581
event.persist()
585582
stopPropagation(event)
586583

587-
setDragTargets([])
584+
dragTargetsRef.current = []
588585
dispatch({ type: 'reset' })
589586

590587
if (isEvtWithFiles(event)) {

0 commit comments

Comments
 (0)