Skip to content

Commit deb4a90

Browse files
authored
fix(useDraggableWithDomApi): placeholder double render (React 18) (#6187)
h2. Описание В **React 18** периодически, по-крайней мере у меня, `onDragMove` вызывается дважды при начале перетаскивания, из-за чего дважды срабатывает `initializeItems()`, в конечном итоге и функция `setInitialPlaceholderItemStyles()`. У @BlackySoul каждый раз `onDragMove` срабатывает джажды. <details><summary>Видео с воспроизведением от @BlackySoul</summary> <p> https://github.com/VKCOM/VKUI/assets/5850354/8d010f2c-a4f4-4497-9a79-69a866dc362d </p> </details> h2. Изменения - `dragging` в `true` теперь выставляем через функцию в `setDragging()`, в аргументы которого мы можем получить следующую транзакцию состояния и проверять не `true` ли уже. - В `setInitialPlaceholderItemStyles()` дополнительно проверяем нет вставлен ли уже элемент.
1 parent a52da39 commit deb4a90

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

packages/vkui/src/hooks/useDraggableWithDomApi/useDraggableWithDomApi.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,16 @@ export const useDraggableWithDomApi = <T extends HTMLElement>({
217217
schedulingAutoScroll();
218218
}
219219
} else {
220-
initializeScrollRefs(draggingEl);
221-
initializeItems(draggingEl);
222-
setDragging(true);
220+
setDragging((prevDragging) => {
221+
// На случай, если onDragMove успеет вызваться ещё раз до того, как `dragging` выставится в
222+
// `true`
223+
if (prevDragging) {
224+
return prevDragging;
225+
}
226+
initializeScrollRefs(draggingEl);
227+
initializeItems(draggingEl);
228+
return true;
229+
});
223230
}
224231
};
225232

@@ -274,5 +281,15 @@ export const useDraggableWithDomApi = <T extends HTMLElement>({
274281
[dragging, handleScroll],
275282
);
276283

284+
useIsomorphicLayoutEffect(
285+
() =>
286+
function componentWillUnmount() {
287+
if (placeholderItemRef.current) {
288+
unsetInitialPlaceholderItemStyles(placeholderItemRef.current);
289+
}
290+
},
291+
[],
292+
);
293+
277294
return { dragging, onDragStart, onDragMove, onDragEnd };
278295
};

packages/vkui/src/hooks/useDraggableWithDomApi/utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export const unsetInitialDraggingItemStyles = ({ el }: DraggingItem) => {
6363
};
6464

6565
export const setInitialPlaceholderItemStyles = ({ el, draggingElRect }: PlaceholderItem) => {
66+
if (el.firstElementChild) {
67+
return;
68+
}
6669
const { width, height } = draggingElRect;
6770
const node = el.cloneNode() as HTMLElement;
6871
node.style.setProperty('display', 'block');

0 commit comments

Comments
 (0)