I'm experiencing this warning with different components in my application but I will take just the following one as example.
I have got the following component. It has a map function that renders multiple components from an array:
const Clipboards = () => {
const { user, addClipboard } = useAuth();
const clipboards = user?.clipboards || [];
return (
<>
{clipboards.map(clipboard =>
<Clipboard clipboard={clipboard}/>
)}
<IconButton onClick={() => addClipboard()} color={'secondary'}>
<PlusIcon/>
</IconButton>
</>
)
};
export default Clipboards;
with Clipboard being as follows. As you can see, I use key prop in the wrapping div:
const Clipboard = ({clipboard, setSelectedClipboard}) => {
const {addClipboardRubric} = useAuth();
const {enqueueSnackbar} = useSnackbar();
const selectClip = () => {
setSelectedClipboard({id: clipboard.id, name: clipboard.name})
};
const [{isActive}, drop] = useDrop(() => ({
accept: 'rubric',
collect: (monitor) => ({
isActive: monitor.canDrop() && monitor.isOver(),
}),
drop(item, monitor) {
handleDrop(item)
},
}));
const handleDrop = async (rubric) => {
try {
await addClipboardRubric({
clipboardId: clipboard.id,
rubric: rubric
})
enqueueSnackbar('Rubric added', {
variant: 'success'
});
} catch (e) {
enqueueSnackbar('Rubric already added', {
variant: 'error'
});
}
}
console.log(`clip-${clipboard.id}`)
return (
<div ref={drop} key={clipboard.id}>
<IconButton
id={`clip-${clipboard.id}`}
onClick={selectClip}
color={'secondary'}
>
<Badge badgeContent={clipboard?.rubrics?.length || 0} color={"secondary"}>
<ClipboardIcon/>
</Badge>
</IconButton>
</div>
)
}
export default connect(
({search: {repertories = {}}}) => ({repertories}),
(dispatch) => ({
setSelectedClipboard: (payload) => dispatch(SET_SELECTED_CLIPBOARD(payload)),
})
)(Clipboard);
As you can see. I'm adding the key and it is unique. What would be the problem then?
CodePudding user response:
You have to add a unique key to every item returned from the map
function. For example, you can use the index as a unique key. In your code, you are adding a key inside the component. You need to add the key to the component itself. Check the below code.
const Clipboards = () => {
const { user, addClipboard } = useAuth();
const clipboards = user?.clipboards || [];
return (
<>
{clipboards.map((clipboard,index) =>
<Clipboard clipboard={clipboard} key={index}/>
)}
<IconButton onClick={() => addClipboard()} color={'secondary'}>
<PlusIcon/>
</IconButton>
</>
)
};
export default Clipboards;
CodePudding user response:
You haven't added a key to the Clipboard component which is returned by the map.
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity.
Try something like this (if Clipboard as an id property):
{clipboards.map(clipboard =>
<Clipboard key={clipboard.id} clipboard={clipboard}/>
)}