1

最近在使用List组件的时候,发现组件没有重新渲染,导致状态发送错误。首先,我复现下代码。


function Other() {
  const [data, setData] = useState([6, 7, 8, 3, 4, 5])
  function handleData() {
    setData([6, 7, 8, 9])
  }
  function handleData1() {
    setData([6,7,8])
  }
  return (
    <>
      <Button onClick={handleData}>12</Button>
      <Button onClick={handleData1}>12</Button>
      <List dataSource={data} renderItem={(item)=><ListData list={item}/>}>
      </List>
    </>
  )
}

function ListData(props) {
  const [check, setCheck] = useState(false)
  console.log(check)
  return <div onClick={() => setCheck(!check)}>{props.list}{check?"  true":"   false"}</div>
}
export default Other

这里我们使用了List组件,这是一个很常用的组件。

但是当我们点击按钮的时候,发现6,7,8三个组件 都没有重新渲染。

我们很容易 就会想到 map key唯一性的问题。 但是如果我们这样改

      <List dataSource={data} renderItem={(item,index)=><ListData list={item} key={index}/>}>
      </List>
      //or
            <List dataSource={data} renderItem={(item,index)=><ListData list={item} key={item}/>}>
      </List>

我们会发现 依然没有用 。组件还是没有被重复渲染

当我们查看 antd文档的时候,也没有关于该解决方案的 props。

所以我们得去查看源码

  renderItem = (item: any, index: number) => {
    const { renderItem, rowKey } = this.props;
    let key;

    if (typeof rowKey === 'function') {
      key = rowKey(item);
    } else if (typeof rowKey === 'string') {
      key = item[rowKey];
    } else {
      key = item.key;
    }

    if (!key) {
      key = `list-item-${index}`;
    }

    this.keys[index] = key;

    return renderItem(item, index);
  };

so, 看到这段代码,看名字我们也可以猜出 rowKey这个属性,就是我们需要使用的方法了。
所以我们将代码修改

      <List dataSource={data} rowKey={()=>uuid()} renderItem={(item,index)=><ListData list={item} key={index}/>}>
      </List>

这样就可以解决,组件没有被重新渲染的问题了


腹中有书气自华
2k 声望63 粉丝

三人行,必有我师