You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Profiler Highlights All Items When Interacting with a Single Draggable Item
Description
Using the React DevTools Profiler, I noticed that when I interact with the drag button of a single item in a sortable list, all items in the list get highlighted in the Profiler, indicating that they are re-rendering. However, when adding a console log in the draggable button (DraggableIconButton), only the interacted button logs a message, suggesting that only one component is truly being re-rendered.
This discrepancy between the Profiler's highlight and the actual logs is confusing. I want to confirm whether this is expected behavior due to React's reconciliation process or a bug in @dnd-kit.
Steps to Reproduce
Create a sortable list using @dnd-kit/core and @dnd-kit/sortable.
Wrap all draggable components with React.memo to prevent unnecessary re-renders.
Use the React DevTools Profiler to observe updates when interacting with a single drag button.
Click or drag one item's button.
Expected Behavior:
The Profiler highlights only the interacted item if it re-renders.
Actual Behavior:
The Profiler highlights all sibling items, even though only one of the list item is touched/clicked. I am worried about when the list grows up and these re renders become very expensive.
Already tried
Use Context Selector to handle the context
Memoizing the listeners and attributes
Memoizing the internal sortable list item
Using useSortable outside the component
Callbacks to wrap the remove functionality
Reproduction Code
Here’s a simplified version of the setup:
App.tsx
importReact,{useState}from"react";import{DndContext,SortableContext}from"@dnd-kit/core";import{useSortable}from"@dnd-kit/sortable";import{CSS}from"@dnd-kit/utilities";constDraggableIconButton=React.memo(({ listeners, attributes, id }: any)=>{console.log(`DraggableIconButton for id=${id} rendered.`);return(<button{...(listeners??{})}{...(attributes??{})}style={{cursor: "grab"}}>
Drag
</button>);});constSortableItem=React.memo(({ id }: {id: string})=>{const{ setNodeRef, transform, transition, listeners, attributes }=useSortable({ id });conststyle={transform: CSS.Transform.toString(transform),
transition,padding: "10px",marginBottom: "5px",backgroundColor: "white",border: "1px solid lightgray",display: "flex",alignItems: "center",};return(<divref={setNodeRef}style={style}>{id}<DraggableIconButtonlisteners={listeners}attributes={attributes}id={id}/></div>);});exportdefaultfunctionApp(){const[items,setItems]=useState(["Item 1","Item 2","Item 3"]);return(<DndContext><SortableContextitems={items}><div>{items.map((item)=>(<SortableItemkey={item}id={item}/>))}</div></SortableContext></DndContext>);}
P.S Great Library and really easy to use. I would really appreciate if someone could guide me on this one.
Profiler showing all three item list being re rendered
Rendering Highlights on click to one of the item list
Hi @NavTheRaj.
What's happening here is that when you drag one of the items it changes the state in causing it's children to re-render, hence the highlighting in profiler.
But since you wrapped the items in React.memo and their props haven't actually changed they don't get re-rendered. The only exception is the item being currently dragged which has the output of one of it's hooks changed causing a re-render.
Title
Profiler Highlights All Items When Interacting with a Single Draggable Item
Description
Using the React DevTools Profiler, I noticed that when I interact with the drag button of a single item in a sortable list, all items in the list get highlighted in the Profiler, indicating that they are re-rendering. However, when adding a console log in the draggable button (
DraggableIconButton
), only the interacted button logs a message, suggesting that only one component is truly being re-rendered.This discrepancy between the Profiler's highlight and the actual logs is confusing. I want to confirm whether this is expected behavior due to React's reconciliation process or a bug in
@dnd-kit
.Steps to Reproduce
@dnd-kit/core
and@dnd-kit/sortable
.React.memo
to prevent unnecessary re-renders.Expected Behavior:
The Profiler highlights only the interacted item if it re-renders.
Actual Behavior:
The Profiler highlights all sibling items, even though only one of the list item is touched/clicked. I am worried about when the list grows up and these re renders become very expensive.
Already tried
Reproduction Code
Here’s a simplified version of the setup:
App.tsx
P.S Great Library and really easy to use. I would really appreciate if someone could guide me on this one.
Profiler showing all three item list being re rendered
Rendering Highlights on click to one of the item list
List of Hooks for an idea of whats being changed
Sandbox Link
React TypeScript Sandbox
The text was updated successfully, but these errors were encountered: