首页 > 解决方案 > react如何区分具有相同父级的两个数组的相似键?

问题描述

在 Dan Abramov 博客文章中,我读到

请注意,键仅在特定的父 React 元素中相关,例如表单。React 不会尝试在不同父级之间使用相同的键“匹配”元素。

所以这里说:

let data = [0, 1];
return (
  <div>
    <div>
      {data.map((x) => (
        <span key={x}>{x}</span>
      ))}
    </div>
    <div>
      {data.map((x) => (
        <span key={x}>{x}</span> // has different parent but same keys
      ))}{" "}
    </div>
  </div>
);

即使跨度元素具有相同的键,React 也不会混淆它们,因为它们属于不同的 parent 。

但是 React 如何区分这种情况呢?

let data = [0, 1];

return (
  <div>
    <span key={0}>0</span>
    {data.map((x) => (
      <span key={x}>{x}</span>
    ))}
    {data.map((x) => (
      <span key={x}>{x}</span>
    ))}
  </div>
);

在这种情况下,和解会正常工作吗?如何?

因为上面的东西会转化为类似的东西:

<div>
  <span key="0">0</span>
  <span key="0">0</span>
  <span key="1">1</span>
  <span key="0">0</span>
  <span key="1">1</span>
</div>

但是我没有收到上述代码的任何警告,所以 React 似乎仍然能够正确地进行协调。

标签: javascriptreactjs

解决方案


我没有确凿的证据,但我不认为这个案例缺少警告。React.Children.toArray我宁愿认为 React在遇到一组孩子时会做类似的事情:

React.Children.toArray() 在展平子列表时更改键以保留嵌套数组的语义。也就是说, toArray 为返回数组中的每个键添加前缀,以便每个元素的键的范围都限定为包含它的输入数组。

所以我的猜测是和解在这里有效。

此外,我个人会在后期渲染阶段实施“重复键”检查,以便捕获所有边缘情况(包括您的示例)。没有警告,所以这是 IMO 一个强有力的线索,表明没有重复的键。


推荐阅读