Skip to content

Commit

Permalink
fix(useDraggableWithDomApi): placeholder double render (React 18) (#6187
Browse files Browse the repository at this point in the history
)

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()` дополнительно проверяем нет вставлен ли уже элемент.
  • Loading branch information
inomdzhon authored and mendrew committed Jan 18, 2024
1 parent 596613d commit 8c7b783
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,16 @@ export const useDraggableWithDomApi = <T extends HTMLElement>({
schedulingAutoScroll();
}
} else {
initializeScrollRefs(draggingEl);
initializeItems(draggingEl);
setDragging(true);
setDragging((prevDragging) => {
// На случай, если onDragMove успеет вызваться ещё раз до того, как `dragging` выставится в
// `true`
if (prevDragging) {
return prevDragging;
}
initializeScrollRefs(draggingEl);
initializeItems(draggingEl);
return true;
});
}
};

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

useIsomorphicLayoutEffect(
() =>
function componentWillUnmount() {
if (placeholderItemRef.current) {
unsetInitialPlaceholderItemStyles(placeholderItemRef.current);
}
},
[],
);

return { dragging, onDragStart, onDragMove, onDragEnd };
};
3 changes: 3 additions & 0 deletions packages/vkui/src/hooks/useDraggableWithDomApi/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ export const unsetInitialDraggingItemStyles = ({ el }: DraggingItem) => {
};

export const setInitialPlaceholderItemStyles = ({ el, draggingElRect }: PlaceholderItem) => {
if (el.firstElementChild) {
return;
}
const { width, height } = draggingElRect;
const node = el.cloneNode() as HTMLElement;
node.style.setProperty('display', 'block');
Expand Down

0 comments on commit 8c7b783

Please sign in to comment.