React Material UI Drawer - Warning Each child in a list should have a unique "key" prop

Viewed 557

I'm using a React MUI Drawer and although I have given key prop to child in the List still getting this warning message when the react mui drawer opens. I have attached some screen shots and sample code that I have written.

Overview Layout

Warning after Drawer Opens

AppBarWithDrawer Component

import React from "react";
// Components
import { Box, AppBar, Toolbar } from "material-ui";
import DrawerMenu from "../navbar/drawerMenu";

export default function appBarWithDrawer() {
  return (
    <Box sx={{ flexGrow: 1 }}>
      <AppBar position="static">
        <Toolbar>
          <DrawerMenu />
        </Toolbar>
      </AppBar>
    </Box>
  );
}

DrawerMenu Component

import React from 'react';
// Components
import { Button, Box, Drawer } from 'material-ui';
import CustomIcon from 'material-ui-icons';
import DrawerMenuList from './drawerMenuList';
// Constants 
import { MENU_ICON } from 'material-ui-icon-types/iconTypes';
import { DASHBOARD_MENU_ICON_THEME } from 'material-ui-icon-types/themeTypes';

export default function DrawerMenu () {

    // Drawer menu type
    const LEFT_MENU_TYPE = 'left';

    const Icon = ({ iconType }) => {
        return (<CustomIcon icon={iconType} theme={DASHBOARD_MENU_ICON_THEME} />);
    };

    // Left Drawer Menu status
    const [state, setState] = React.useState({
        left: false
    });

    const toggleDrawer = (anchor) => (event) => {
        if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
            return;
        }
        setState({ ...state, [anchor]: !state.left });
    };

    const list = (anchor) => (
        <Box
            sx={{ width: 240 }}
            role="presentation"
            onClick={toggleDrawer(anchor)}
            onKeyDown={toggleDrawer(anchor)}
        >
            <DrawerMenuList />
        </Box>
    );


    return (
            <div>
                <Button className="navHamburgerButton" onClick={toggleDrawer(LEFT_MENU_TYPE)}> 
                   <Icon iconType={MENU_ICON} />
                </Button>
                <Drawer
                    anchor={LEFT_MENU_TYPE}
                    open={state[LEFT_MENU_TYPE]}
                    onClose={toggleDrawer(LEFT_MENU_TYPE)}
                >
                    {list(LEFT_MENU_TYPE)}
                </Drawer>
            </div>
    );
}

I have included the key prop in the each child in a list of the below component as shown but still getting the warninig.

DrawerMenuList Component

import React from 'react';
import { List, Divider, ListItem, ListItemIcon, ListItemText } from 'material-ui';
import CustomIcon from 'material-ui-icons';
import {
    SCHOOL_OUTLINED_ICON, SPEED_OUTLINED_ICON, FORMAT_LIST_NUMBERED_RTL_ICON,
    CREATE_OUTLINED_ICON
} from 'material-ui-icon-types/iconTypes';
import { DASHBOARD_MENU_ICON_THEME } from 'material-ui-icon-types/themeTypes';

export default function DrawerMenuList () {

    // Reusable icon for the Drawer List. The "DASHBOARD_MENU_ICON_THEME" theme is applied.
    const Icon = ({ iconType }) => {
        return (<CustomIcon icon={iconType} theme={DASHBOARD_MENU_ICON_THEME} />);
    };

    const drawerItems = [
        {
            id: Math.random(),
            name: 'Dashboard',
            icon: SPEED_OUTLINED_ICON
        },
        {
            id: Math.random(),
            name: 'Syllabus',
            icon: FORMAT_LIST_NUMBERED_RTL_ICON
        },
        {
            id: Math.random(),
            name: 'Notes & Highlights',
            icon: CREATE_OUTLINED_ICON
        },
        {
            id: Math.random(),
            name: 'Virtusal Classroom',
            icon: SCHOOL_OUTLINED_ICON

        }
    ];

    return (
            <List>
                {drawerItems.map((item) => (
                    <ListItem button key={item.id}>
                        <ListItemIcon>
                            <Icon iconType={item.icon} />
                        </ListItemIcon>
                        <ListItemText primary={item.name} />
                    </ListItem>
                ))}
            </List>
    );
}

When I debug in the browser the error fires when executing the below section

Warning Fires when executing these lines

2 Answers

This error is because you are not giving a key to the child as it should. I had this same error, I found the solution in the examples of MUI. I will leave you the link for the documentation and examples

This is the image of the example from MUI In this picture you can see that the anchor is set in a Fragment that is covering the whole button and drawer.

From this:

return (
        <List>
            {drawerItems.map((item) => (
                <ListItem button key={item.id}>
                    <ListItemIcon>
                        <Icon iconType={item.icon} />
                    </ListItemIcon>
                    <ListItemText primary={item.name} />
                </ListItem>
            ))}
        </List>
);

You can try This:

return (
   <List>
       {drawerItems.map((item) => (
        <React.Fragment key={item.id}>
           <ListItem button>
               <ListItemIcon>
                   <Icon iconType={item.icon} />
               </ListItemIcon>
               <ListItemText primary={item.name} />
           </ListItem>
         </React.Fragment>
       ))}
   </List>
);

Ideally your code should work as you are assigning key. You could try this code once.

<List>
   {drawerItems.map((item, index) => (
      <ListItem button key={index}>
         ...
      </ListItem>
   ))}
</List>
Related