Skip to content

Commit

Permalink
React 18 <StrictMode> tweaks and bug fixes (#788)
Browse files Browse the repository at this point in the history
* Enable strict mode in storybook
* Remove unnecessary requestAnimationFrame
* Fix issues with droppable measuring in strict mode
  • Loading branch information
clauderic committed Jan 4, 2023
1 parent d5c4732 commit da94c02
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 43 deletions.
6 changes: 6 additions & 0 deletions .changeset/mean-doors-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@dnd-kit/core": patch
"@dnd-kit/sortable": patch
---

Bug fixes for React 18 Strict Mode
1 change: 1 addition & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const path = require('path');
module.exports = {
reactOptions: {
legacyRootApi: false,
strictMode: true,
},
staticDirs: ['./assets'],
stories: ['../stories/**/*.story.tsx'],
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/hooks/useDraggable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ export function useDraggable({
draggableNodes,
over,
} = useContext(InternalContext);
const {role = defaultRole, roleDescription = 'draggable', tabIndex = 0} =
attributes ?? {};
const {
role = defaultRole,
roleDescription = 'draggable',
tabIndex = 0,
} = attributes ?? {};
const isDragging = active?.id === id;
const transform: Transform | null = useContext(
isDragging ? ActiveDraggableContext : NullContext
Expand Down
52 changes: 24 additions & 28 deletions packages/core/src/hooks/utilities/useDroppableMeasuring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@ export function useDroppableMeasuring(
containers: DroppableContainer[],
{dragging, dependencies, config}: Arguments
) {
const [
containerIdsScheduledForMeasurement,
setContainerIdsScheduledForMeasurement,
] = useState<UniqueIdentifier[] | null>(null);
const measuringScheduled = containerIdsScheduledForMeasurement != null;
const [queue, setQueue] = useState<UniqueIdentifier[] | null>(null);
const {frequency, measure, strategy} = config;
const containersRef = useRef(containers);
const disabled = isDisabled();
Expand All @@ -50,9 +46,13 @@ export function useDroppableMeasuring(
return;
}

setContainerIdsScheduledForMeasurement((value) =>
value ? value.concat(ids) : ids
);
setQueue((value) => {
if (value === null) {
return ids;
}

return value.concat(ids.filter((id) => !value.includes(id)));
});
},
[disabledRef]
);
Expand All @@ -63,13 +63,11 @@ export function useDroppableMeasuring(
return defaultValue;
}

const ids = containerIdsScheduledForMeasurement;

if (
!previousValue ||
previousValue === defaultValue ||
containersRef.current !== containers ||
ids != null
queue != null
) {
const map: RectMap = new Map();

Expand All @@ -79,9 +77,9 @@ export function useDroppableMeasuring(
}

if (
ids &&
ids.length > 0 &&
!ids.includes(container.id) &&
queue &&
queue.length > 0 &&
!queue.includes(container.id) &&
container.rect.current
) {
// This container does not need to be re-measured
Expand All @@ -104,13 +102,7 @@ export function useDroppableMeasuring(

return previousValue;
},
[
containers,
containerIdsScheduledForMeasurement,
dragging,
disabled,
measure,
]
[containers, queue, dragging, disabled, measure]
);

useEffect(() => {
Expand All @@ -123,17 +115,21 @@ export function useDroppableMeasuring(
return;
}

requestAnimationFrame(() => measureDroppableContainers());
measureDroppableContainers();
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[dragging, disabled]
);

useEffect(() => {
if (measuringScheduled) {
setContainerIdsScheduledForMeasurement(null);
}
}, [measuringScheduled]);
useEffect(
() => {
if (queue && queue.length > 0) {
setQueue(null);
}
},
//eslint-disable-next-line react-hooks/exhaustive-deps
[JSON.stringify(queue)]
);

useEffect(
() => {
Expand All @@ -157,7 +153,7 @@ export function useDroppableMeasuring(
return {
droppableRects,
measureDroppableContainers,
measuringScheduled,
measuringScheduled: queue != null,
};

function isDisabled() {
Expand Down
11 changes: 2 additions & 9 deletions packages/sortable/src/components/SortableContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export function SortableContext({
droppableRects,
over,
measureDroppableContainers,
measuringScheduled,
} = useDndContext();
const containerId = useUniqueId(ID_PREFIX, id);
const useDragOverlay = Boolean(dragOverlay.rect !== null);
Expand All @@ -77,16 +76,10 @@ export function SortableContext({
const disabled = normalizeDisabled(disabledProp);

useIsomorphicLayoutEffect(() => {
if (itemsHaveChanged && isDragging && !measuringScheduled) {
if (itemsHaveChanged && isDragging) {
measureDroppableContainers(items);
}
}, [
itemsHaveChanged,
items,
isDragging,
measureDroppableContainers,
measuringScheduled,
]);
}, [itemsHaveChanged, items, isDragging, measureDroppableContainers]);

useEffect(() => {
previousItemsRef.current = items;
Expand Down
7 changes: 6 additions & 1 deletion packages/sortable/src/hooks/useSortable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ export function useSortable({
() => items.slice(items.indexOf(id)),
[items, id]
);
const {rect, node, isOver, setNodeRef: setDroppableNodeRef} = useDroppable({
const {
rect,
node,
isOver,
setNodeRef: setDroppableNodeRef,
} = useDroppable({
id,
data,
disabled: disabled.droppable,
Expand Down
4 changes: 1 addition & 3 deletions packages/sortable/src/hooks/utilities/useDerivedTransform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ export function useDerivedTransform({disabled, index, node, rect}: Arguments) {

useEffect(() => {
if (derivedTransform) {
requestAnimationFrame(() => {
setDerivedtransform(null);
});
setDerivedtransform(null);
}
}, [derivedTransform]);

Expand Down

0 comments on commit da94c02

Please sign in to comment.