diff --git a/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx b/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx index f4f73fd72..8982ea83c 100644 --- a/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx +++ b/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx @@ -177,20 +177,28 @@ const Item = ({ id, }); - const Handle = (props: Partial) => { - return ( - - - - ); - }; + // Declared with useMemo because it is passed to a child as `handle={Handle}`, i.e. as a component + // *type*. A type that changes identity makes React unmount and remount the subtree rather than + // update it, and this component re-renders on every frame of a drag as dnd-kit updates `transform` + // — so the drag handle was being torn down and rebuilt continuously while being dragged. + const Handle = useMemo( + () => + function DragHandle(props: Partial) { + return ( + + + + ); + }, + [listeners, setActivatorNodeRef], + ); return (