关于 useList 使用 Fragment 组件出现 key 警告的问题

594 阅读1分钟

问题复现

在 js 函数组件中,需要根据数组动态生成组件,用到 react-use 中的 useList,很容易想到用 Array.prototype.map 方法,而且在使用 JSX 语法生成组件的时候,要加 key,我这里使用了 nanoid 这个包来生成随机 key:


import React from 'react'
import { nanoid } from 'nanoid'
import useList from 'react-use/esm/useList'
import SubComponent from './SubComponent'

/* ... */

const Parent = () => {
  const [dynamicSubComponents, {
    clear, push
  }] = useList(<></>)
  
  const fetchData = async () => {
    const arr = await fetch('/api/somedata').then(r = r.json())
    if (Array.isArray(arr)) {
      const temp = arr.map(item => <SubComponent key={nanoid(10)} />)
      push(...temp)
    }
  }
  
  useEffect(() => {
    clear()
    fetchData()
  }, [])
  
  return <>
    {dynamicSubComponents}
  </>
}

export default Parent

这样看起来没什么问题,但是控制台始终会报一个关于组件 Parent 中子元素的 key 错误。

解决方法

将 useList 的初始化值 [<></>] 改为 [<React.Fragment key={nanoid(10)}/>] 即可。

方法2:使用 TypeScript

之所以要传递初始化值,是因为在 JavaScript 环境中,hook 的泛型类型 ts 提示,是根据初始化值来断定的。如果直接使用 typescript 环境就没这个问题了。

const [dynamicSubComponents, {
  clear, push
}] = useList<SubComponent>([])