Home > Mobile >  React: Warning: Each child in a list should have a unique "key" prop
React: Warning: Each child in a list should have a unique "key" prop

Time:02-19

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?

showing unique keys

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.

Source

Try something like this (if Clipboard as an id property):

{clipboards.map(clipboard =>
  <Clipboard key={clipboard.id} clipboard={clipboard}/>
)}

Read this before using the index as a key

  • Related