首页 > 解决方案 > 查找缺少唯一键的子元素?(反应JS)

问题描述

我目前有这段代码,它正在工作,但它抛出了一个警告:列表中的每个孩子都应该有一个唯一的“关键”道具。

Check the render method of `TopMenuDropdown`. See https://reactjs.org/link/warning-keys for more information.
MenuItem@http://localhost:3000/protis-react/static/js/vendors~main.chunk.js:2815:110
TopMenuDropdown@http://localhost:3000/protis-react/static/js/main.chunk.js:2432:5
div
div
App@http://localhost:3000/protis-react/static/js/main.chunk.js:63:5
Router@http://localhost:3000/protis-react/static/js/vendors~main.chunk.js:174391:30
BrowserRouter@http://localhost:3000/protis-react/static/js/vendors~main.chunk.js:174011:35

对我。我什至不知道在哪里找到丢失的钥匙,或者我错过了把它放在哪里。我可以通过任何方式跟踪它,或者这里有人能够找到需要唯一钥匙的丢失元素。我试图在我最初生成的几乎所有东西上放一个密钥,但我不确定哪里出了问题,这一直困扰着我。

import React from 'react';
import {Menu, MenuButton, MenuDivider, MenuItem, SubMenu} from '@szhsin/react-menu';
import '@szhsin/react-menu/dist/index.css'

const tooltipStyle = {
    position: "absolute",
    pointerEvents: "none",
    backgroundColor: "#D7D7A6",
    border: "1px solid",
    padding: "1px 8px",
    whiteSpace: "nowrap",
    zIndex: 200
};

class TopMenuDropdown extends React.Component {

    state = {
        pos: {x: 0, y: 0},
        tooltip: '',
        show: false
    };

    createTooltip = (tooltip) => ({
        onMouseEnter: ({clientX, clientY}) => {
            this.setState(
                {
                    pos: {x: clientX, y: clientY},
                    tooltip: tooltip,
                    show: true
                }
            );
        },
        onMouseLeave: () => {
            this.setState(
                {
                    show: false
                }
            )
        }
    });

    handleSelect = ({value}) => {
        this.props.onClick(value);
    }

    renderMenuItem(menuAnchor, menuItems, isSubMenu) {
        if (isSubMenu) {
            return (
                <SubMenu key={menuAnchor.id}
                         label={
                             <div
                                 key={menuAnchor.id}
                                 {...this.createTooltip(menuAnchor.attributes.title)}
                             >
                                 {menuAnchor['#text']}
                             </div>
                         }
                >
                    {this.menuGeneration(menuItems, menuAnchor)}
                </SubMenu>
            );
        }

        return (
            <>
                <Menu
                    style={{display: 'flex', float: 'left'}}
                    key={menuAnchor.id}
                    menuButton={
                        <MenuButton
                            key={menuAnchor.id}
                            {...this.createTooltip(menuAnchor.attributes.title)}>
                            {menuAnchor['#text']}
                        </MenuButton>}
                    onChange={({open}) => !open && this.setState({show: false})}
                >

                    {this.menuGeneration(menuItems, menuAnchor)}
                </Menu>
                {this.state.show && (
                    <div
                        key={menuAnchor.id}
                        style={{
                            ...tooltipStyle,
                            left: this.state.pos.x,
                            top: this.state.pos.y
                        }}
                    >
                        {this.state.tooltip}
                    </div>
                )}
            </>

        );
    }

    menuGeneration(menuItems, menuAnchor) {

        if (menuItems === undefined) {
            return <></>;
        }

        if (!Array.isArray(menuItems)) {
            menuItems = [menuItems];
        }

        return (
            menuItems.map(({a, attributes, ul}) => {
                    if (ul !== undefined && ul.li !== undefined) {
                        return (
                            this.renderMenuItem(a, ul.li, true)
                        );
                    }

                    if (a === undefined) {
                        return (
                            <MenuDivider key={menuAnchor.id} />
                        )
                    }

                    return (
                        <MenuItem
                            key={menuAnchor.id}
                            value={a.attributes.id}
                            onClick={(id) => this.handleSelect(id)}
                            {...this.createTooltip(a.attributes.title)}
                        >
                            {a['#text']}
                        </MenuItem>)

                }
            )
        )
    }

    render() {

        if (!this.props.topMenu.hasOwnProperty('ul')) {
            return null;
        }

        const menuItemRendering = this.props.topMenu.ul.li.map(({a, ul}) => {
            return this.renderMenuItem(a, ul.li, false);
        });

        return (
            <div style={{display: 'flex'}}>
                {menuItemRendering}
            </div>
        )
    }
}

export default TopMenuDropdown;

标签: javascriptreactjs

解决方案


尝试直接在 menuGeneration 中替换为 for 项目key={menuAnchor.id}key={a.id}

if (a === undefined) {
  return <MenuDivider key={a.id} />
}

return (
  <MenuItem
    key={a.id}
     value={a.attributes.id}
     onClick={(id) => this.handleSelect(id)}
     {...this.createTooltip(a.attributes.title)}
  >
    {a['#text']}
  </MenuItem>
)

推荐阅读