You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React列表key警告修复 函数组件Materialize汉堡菜单实现

修复方案

一、"Each child in a list should have a unique 'key' prop" 警告修复

问题原因

两处遍历categories数组渲染列表的代码存在两个错误:

  • map回调的单个元素参数是category,但代码里错误引用了整个数组对象categories的属性,数组本身不存在id/route/name字段,导致所有渲染项的key值都是undefined,不满足唯一key要求
  • key属性需要绑定在遍历返回的最外层根元素上,当前代码错误把key绑在了内部的NavLink组件上,外层<li>作为列表直接子元素没有拿到key

修复代码

把桌面端导航、移动端侧边栏两处的map遍历逻辑统一替换为以下写法:

{
  categories.map((category) => (
    <li key={category.id}>
      <NavLink to={category.route}>{category.name}</NavLink>
    </li>
  ))
}

二、函数组件下Materialize汉堡侧边栏功能实现

实现逻辑

类组件中一般在componentDidMount生命周期初始化Materialize的JS交互实例,函数组件中使用useEffect钩子实现等价的挂载后初始化逻辑即可,步骤如下:

  • 补充引入React的useEffect钩子,以及Materialize的JS交互模块(之前只引入了CSS样式,缺少交互逻辑代码)
  • 在组件挂载完成后调用Materialize的Sidenav初始化方法,绑定侧边栏触发逻辑
  • 组件卸载时销毁侧边栏实例,避免内存泄漏

修复后完整组件代码

import React, { useEffect } from 'react';
import M from 'materialize-css';
import 'materialize-css/dist/css/materialize.css';
import logo from '../MKY.png';
import Cart from './CartWidget';
import { Link, NavLink} from 'react-router-dom';

const Navbar = () => { 
  const categories = [
    { name: "electronics", id: 0, route: "/category/electronics" },
    { name: "jewelery", id: 1, route: "/category/jewelery" },
    { name: "men's clothing", id: 2, route: "/category/men's clothing" },
    { name: "women's clothing", id: 3, route: "/category/women's clothing" },
  ];

  useEffect(() => {
    // 初始化侧边栏实例
    const sidenavElements = document.querySelectorAll('.sidenav');
    const sidenavInstances = M.Sidenav.init(sidenavElements, {
      edge: 'left',
      draggable: true
    });
    // 组件卸载时销毁实例
    return () => {
      sidenavInstances.forEach(instance => instance.destroy());
    }
  }, []);

  return (
    <>
      <nav className='navMKY'>
        <div className='nav-wrapper'>
          <Link to='/' className='brand-logo'>
            <img src={logo} className="App-logo2" alt="logo" />
          </Link>
          <Link to="#!" data-target="mobile-demo" className='sidenav-trigger'>
            <i className='material-icons'>menu</i>
          </Link>
          <ul className='right hide-on-med-and-down'>
            <li><Link to="/">Index</Link></li>
            {
              categories.map((category) => (
                <li key={category.id}>
                  <NavLink to={category.route}>{category.name}</NavLink>
                </li>
              ))
            }
            <li><Link to="/cart"> <Cart NumberSell={5}/></Link></li>
          </ul>
        </div>
      </nav>

      <ul className='sidenav red ' id="mobile-demo">
        {/* 补充li标签包裹logo,符合Materialize侧边栏DOM结构规范 */}
        <li>
          <Link to='/' className='brand-logo'>
            <img src={logo} className="App-logo2" alt="logo" />
          </Link>
        </li>
        <li><Link to="/">Index</Link></li>
        {
          categories.map((category) => (
            <li key={category.id}>
              <NavLink to={category.route}>{category.name}</NavLink>
            </li>
          ))
        }
        <li><Link to="/cart"> <Cart NumberSell={5}/></Link></li>
      </ul>
    </>
  );
}
export default Navbar;

小提示:如果需要点击侧边栏导航项后自动收起侧边栏,可以给NavLink增加点击事件,调用实例的close()方法即可。


内容的提问来源于stack exchange,提问作者Juan Pablo Grover Pinto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:57:14