react-beautiful-dnd
react-beautiful-dnd copied to clipboard
`Non-consecutive index` error when using redux thunk even with array index passed to droppable index
I have a droppable list whose list items can be reordered. onDragEnd
dispatches a redux thunk action that calls the api and updates the state which gets passed to the component that renders the droppable list. DragDropContext
is outside of the component. App will be served via nextjs with server side rendering and resetServerContext()
before rendering each page server side.
Expected behavior
On drop the animation takes place, onDragEnd
dispatches the action causing the api call, because of the response delay the UI will glitch (no reordering will be rendered), the response returns and the list renders in the correct order.
After that item reordering should still be possible without any glitches, errors, etc.
Actual behavior
After first movement, reordering of the previously moved item is not possible and the console prints
Unable to find draggable with id: {"type":"FoodPlanPosition","foodPlanPositionId":12}
When dragging another item the UI is simply broken and the console prints
Detected non-consecutive <Draggable /> indexes.(This can cause unexpected bugs)0, [🔥2], 3, 4, 5
The strange thing is that the list items droppable index will be taken from array index which can't get non-consecutive:
{props.baseFoodPlanPositions.map((position, idx) => {
return (
<Draggable
key={idx}
index={idx}
draggableId={buildFoodPlanPositionDraggableId(position.id)}
>
{(provided, _snapshot) => {
return (
<ListItem
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
button
className={classes.dailyFoodPlanPosition}
>
{position.foodPlanComponent.name}
</ListItem>
)
}}
</Draggable>
)
})}
Even react component inspector and heavy debugging revealed that the dnd draggable and droppable gets their right id
and index
.
Draggable and Droppable ids are unique (contain database primary key).
In addition I observed strange behavior when adding droppables too fast, whose surrounding components gets rendered via the lifecycle depicted above (click, dispatch, API call, response, stateChange, render). When Items from other lists will be dropped there, they get the wrong droppable ID and therefore will be appended to the wrong list.
This seems to be some kind of race condition and hope anyone can provide a hint where to start. I tried to rebuild the scenario (redux managed list) via code sandbox, but can't emulate API calls and nextjs there.
Steps to reproduce
IMHO too complex to provide currently - If the details provided above are too vague and analysis of the problem is not possible, I'll break things down and provide one.
Current one that uses redux, but no API calls and nextjs, and has no unexpected behavior: https://codesandbox.io/s/react-redux-material-ui-react-beautiful-dnd-bug-itp55
What version of React
are you using?
[email protected]:
version "16.9.0"
What version of react-beautiful-dnd
are you running?
react-beautiful-dnd@^13.0.0:
version "13.0.0"
What browser are you using?
latest Chrome
Demo
I used the array index as ReactElement key, which lead to the error.
Is it possible to move the hint https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/api/draggable.md#keys-for-a-list-of-draggable- into the section required-props
? After reaching optional pros I just scanned over the site and missed the point of key
. Even better to point to the equal important key
at the index
rule and even at setup problems.
I'm running into the same problem. Did you find a way out by any chance? Thanks! @rolandjohann
Even I am running into same problem. Any way out for this issue?
facing same issue, is fix expected? when?
I am running into the same issue. Has there been a fix for it?
I'm also facing this issue. Any solution?
The OP mentions the solution (see the doc in the 2nd comment)
Moreover, I think the issue is that the tutorial on egghead doesn't specify key
for a draggable either - which can potentially lead to a lot of users facing the issue
The OP mentions the solution (see the doc in the 2nd comment) Moreover, I think the issue is that the tutorial on egghead doesn't specify
key
for a draggable either - which can potentially lead to a lot of users facing the issue
In the egghead tutorial, the Draggable
component is inside the child list component
but in the code shown in this issue, the Draggable
component is wrapping the child list component.
In order to add the key
property on the Draggable
component, is it better to have the code structure as in the first or second scenario? @yogeshnachnani
I was following the tutorial and bump into the same problem.
I just add the key property to my Draggable component and everything start to work as expected.
change from this
<Draggable draggableId={id} index={index}>
{(provided) => (
<div {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}>
<Tile>
<p>{id}</p>
</Tile>
</div>
)}
</Draggable>
to this
<Draggable key={id} draggableId={id} index={index}>
{(provided) => (
<div {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}>
<Tile>
<p>{id}</p>
</Tile>
</div>
)}
</Draggable>
Change this:
<Draggable draggableId={id} index={index}>
{(provided) => (
<div {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}>
<Tile>
<p>{id}</p>
</Tile>
</div>
)}
</Draggable>
to
<Draggable draggableId={id} key={id} index={index}>
{(provided) => (
<div {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}>
<Tile>
<p>{id}</p>
</Tile>
</div>
)}
</Draggable>
Don't use index as the key
Experienced the same problem. Adding item.id as a key to the <Draggable> helped (index did not)
Thanks @spmsupun for pointing out to do not use index as key.
Change this:
<Draggable draggableId={id} index={index}> {(provided) => ( <div {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}> <Tile> <p>{id}</p> </Tile> </div> )} </Draggable>
to
<Draggable draggableId={id} key={id} index={index}> {(provided) => ( <div {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}> <Tile> <p>{id}</p> </Tile> </div> )} </Draggable>
Don't use index as the key
In my case the problem was in the draggableId, I was using non-unique field :) Just in case someone stumbles into this as well
@pierluigi-giancola Thanks a lot 🚀❤️
I was following the tutorial and bump into the same problem.
I just add the key property to my Draggable component and everything start to work as expected.
change from this
<Draggable draggableId={id} index={index}> {(provided) => ( <div {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}> <Tile> <p>{id}</p> </Tile> </div> )} </Draggable>
to this
<Draggable key={id} draggableId={id} index={index}> {(provided) => ( <div {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}> <Tile> <p>{id}</p> </Tile> </div> )} </Draggable>
it's solved my problem, thanks a lot.
Reading through the comments here you more or less ran into the same usage error as me 😅. Since there is no real issue and I forgot to close this back 2020 , I'll do it now.