React Material UI 抽屉 - 警告:列表中的每个子元素都应该有一个唯一的 "key" 属性。

4
我正在使用React MUI抽屉,虽然我已经在列表中给子元素提供了key属性,但当React MUI抽屉打开时仍会收到警告消息。我附上了一些屏幕截图和示例代码。

Overview Layout

Warning after Drawer Opens

AppBarWithDrawer组件

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>
  );
}

抽屉菜单组件
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>
    );
}

我已经在下面组件的每个子项中包含了关键 prop,如所示,但仍然收到警告。
抽屉菜单列表组件
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>
    );
}

当我在浏览器中调试时,执行以下部分时会触发错误。

Warning Fires when executing these lines


即使我传递了唯一的“key”,在使用mui的“ListItem”后,我仍然会收到相同的警告。显然,这需要由库开发人员进行修复。 - user1451111
2个回答

2
这个错误是因为您没有给子元素设置键(key)。 我曾经遇到了同样的错误,在 MUI 的示例中找到了解决方案。 我会为您留下文档示例的链接。

这是来自 MUI 的示例图片 在这张图片中,可以看到锚点设置在一个覆盖整个按钮和抽屉的 Fragment 中。

从这里开始:

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

你可以尝试这样做:
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>
);

0
理想情况下,您的代码应该像分配密钥一样工作。您可以尝试运行此代码。
<List>
   {drawerItems.map((item, index) => (
      <ListItem button key={index}>
         ...
      </ListItem>
   ))}
</List>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接