每个 child 都应该有一个独特的关键道具,即使它们已设置 - REACT

Each child should have a unique key prop even they're set - REACT

我从这样的 json 文件中获取我的导航栏路线:

{
  "categorias": [
    {
      "nombre": "Faltas de profesorado",
      "componentes": [
        {
          "type": "url",
          "icon": "fas fa-plus",
          "title": "Nueva falta",
          "url": "/"
        },
        {
          "type": "url",
          "icon": "fas fa-comment",
          "title": "Gestionar faltas",
          "url": "/"
        },{
              "type": "desplegable",
              "title": "Reservar un moscoso",
              "url": "/",
              "items": [
                {
                  "type": "url",
                  "title": "Moscoso de urgencia",
                  "url": "/"
                }

              ]
            }
      ]
    }
  ]
}

然后我将它们映射到我的组件中。

我尝试将所有键更改为 nanoid(6) 以获取随机字符串。仍然没有成功。

const NavRoutes = ({rutas}) => (
  /* Mapeo de rutas */
  rutas.map(ruta => (<div className={styles.NavigationBar__routes__wrapper} key={nanoid(6)}>
    <div open={true} className={styles.NavigationBar__routes__name__container} onClick={(e) => e.currentTarget.toggleAttribute('open')}>
      <i className={`${styles.icon} fas fa-arrow-right`}/>
      <h5 className={styles.NavigationBar__routes__name}>{ruta.nombre}</h5>
    </div>
    <div className={styles.NavigationBar__routes__container}>
    {
      (ruta.componentes?.length > 0)?
      ruta.componentes.map((subRuta,i) => (
        <ul key={nanoid(6)} className={styles.NavigationBar__route__list}>
          <li key={nanoid(6)}>
            <i className={`${styles.icon} ${subRuta.icon}`}/>
            <Link to={`${subRuta.url}`}>{subRuta.title}</Link>
          </li>
        {
          (subRuta.items?.length > 0 && subRuta.type === 'desplegable')
          ?
          <ul key={nanoid(6)}>
          {subRuta.items.map((item,i) => (<>
            <li key={nanoid(6)}>
              <Link to={`${item.url}`}>{item.title}</Link>
            </li>
            {(item.items?.length > 0)
              ?
              item.items.map(extra => (
                <ul key={nanoid(6)}>
                  <li><Link to={`${item.url}`}>{extra.title}</Link></li>
                </ul>
                ))
              :
              ''
            }
          </>))}
          </ul>
          :
          ''
        }
        </ul>
        )
      )
      :
      'Vacio'
    }
    </div>
  </div>))
  /* Fin mapeo de rutas */
)

并将它们映射到我的 NavBar 组件中。

一切正常,但在我的控制台中出现错误,即使我已经在每个映射元素之后定义了一个键(没有元素具有相同的键):

should have a unique "key" prop.

Check the render method of `NavRoutes`. See
https://reactjs.org/link/warning-keys for more information.
    at NavRoutes (http://localhost:3000/static/js/bundle.js:544:5)
    at div
    at div
    at http://localhost:3000/static/js/bundle.js:33611:5
    at nav
    at NavBar (http://localhost:3000/static/js/bundle.js:675:69)
    at div
    at Home
    at Index (http://localhost:3000/static/js/bundle.js:1826:66)
    at Routes (http://localhost:3000/static/js/bundle.js:64433:5)
    at Router (http://localhost:3000/static/js/bundle.js:64366:15)
    at BrowserRouter (http://localhost:3000/static/js/bundle.js:63842:5)
    at AuthProvider (http://localhost:3000/static/js/bundle.js:1434:5)
    at App ```

有人可以看看吗?我已经尝试了很多 none 工作。

固定

错误在这里,片段没有密钥。

subRuta.items.map((item,i) => (<>
            <li key={nanoid(6)}>
              <Link to={`${item.url}`}>{item.title}</Link>
            </li>
            {(item.items?.length > 0)
              ?
              item.items.map(extra => (
                <ul key={nanoid(6)}>
                  <li><Link to={`${item.url}`}>{extra.title}</Link></li>
                </ul>
                ))
              :
              ''
            }
          </>))

将片段更改为 ul。谢谢大家

subRuta.items.map((item,i) => (<ul key={nanoid(6)}>
            <li>
              <Link to={`${item.url}`}>{item.title}</Link>
            </li>
            {(item.items?.length > 0)
              ?
              item.items.map(extra => (
                <ul key={nanoid(6)}>
                  <li><Link to={`${item.url}`}>{extra.title}</Link></li>
                </ul>
                ))
              :
              ''
            }
          </ul>))

您应该将键设置为索引,而不是标题。这样如果你有重复的标题,它就不会有重复的键。

     {subRuta.items.map((item, index) => (<>
        <li key={index}>
          <Link to={`${item.url}`}>{item.title}</Link>
        </li>
        {(item.items?.length > 0)
          ?
          item.items.map((extra, index) => (
            <ul key={index}>
              <li><Link to={`${item.url}`}>{extra.title}</Link></li>
            </ul>
            ))
          :
          ''
      }

此外,您给 wayyyy 的钥匙太多了 div。看第一张地图 - 每个 div 上都有一把钥匙。删除所有这些。您只需要在循环的第一个 div 上使用键。

这一节有3个键,其中2个完全相同key={'${ruta.nombre}-container'}。您唯一需要的是第一个。

   <div className={styles.NavigationBar__routes__wrapper} key={ruta.nombre}>
    <div key={`${ruta.nombre}-container`} open={true} className={styles.NavigationBar__routes__name__container} onClick={(e) => e.currentTarget.toggleAttribute('open')}>
      <i className={`${styles.icon} fas fa-arrow-right`}/>
      <h5 className={styles.NavigationBar__routes__name}>{ruta.nombre}</h5>
    </div>
    <div key={`${ruta.nombre}-list-container`} className={styles.NavigationBar__routes__container}>

除了@gwalsgington 的回答,您还可以在您的项目中使用 nanoid 这样的随机字符串生成器。然后你可以在将 nanoid 导入为 import { nanoid } from 'nanoid':

后像这样使用它
{subRuta.items.map(item => (<>
        <li key={nanoid(4)}>
          <Link to={`${item.url}`}>{item.title}</Link>
        </li>
        {(item.items?.length > 0)
          ?
          item.items.map(extra => (
            <ul key={nanoid(4)}>
              <li><Link to={`${item.url}`}>{extra.title}</Link></li>
            </ul>
            ))
          :
          ''
      }

添加随机键来反应片段也对我有帮助。从 'nanoid' 导入 {nanoid} 并将其传递给片段中的键 ()