Javascript react如何区分具有相同父级的两个数组的相似键?

Javascript react如何区分具有相同父级的两个数组的相似键?,javascript,reactjs,Javascript,Reactjs,在丹·阿布拉莫夫的博客文章中,我读到 请注意,该键仅在特定父级中相关 元素,如窗体。React不会尝试与元素“匹配” 在不同的父级之间使用相同的密钥 这里说: let data = [0, 1]; return ( <div> <div> {data.map((x) => ( <span key={x}>{x}</span> ))} </div> <div&

在丹·阿布拉莫夫的博客文章中,我读到

请注意,该键仅在特定父级中相关 元素,如窗体。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不会混淆span元素,即使它们具有相同的键,因为它们属于不同的父元素

但是,例如,在这种情况下,我们将如何反应

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似乎仍然能够正确地进行对账。

它应该警告您,它只在没有密钥时发出警告,但是如果您开始操作这些元素的状态,您可能会遇到问题。

它应该警告您,它只在没有密钥时发出警告,但是如果你开始操纵这些元素的状态,你可能会遇到问题。

我没有确切的证据,但我不认为这个案例缺少警告。我更倾向于假设React在遇到一系列孩子时会这样做:

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

所以我猜和解在这里起作用


此外,我个人会在后期渲染阶段实现一个重复的关键点检查,以便捕获包括您的示例在内的所有边缘情况。没有警告,所以这是一个强有力的线索,没有重复的钥匙。

我没有确切的证据,但我不认为这个案例缺少警告。我更倾向于假设React在遇到一系列孩子时会这样做:

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

所以我猜和解在这里起作用


此外,我个人会在后期渲染阶段实现一个重复的关键点检查,以便捕获包括您的示例在内的所有边缘情况。没有任何警告,因此这是一个很强的线索,表明没有重复的键。

我对其工作原理缺乏正确的理解,但键实际上不是实际DOM上的属性。我想你很清楚这一点,但我想这仍然是关键,这里没有双关语。React在内部处理两个元素数组,因此存在某种形式的作用域。@hotpink是的,我只是将其放在DOM上以说明我的观点。是的,可能有某种形式的作用域,你们是对的,我还在数组之前的示例中手动添加了一个跨度。但是要回答这个问题,你必须确切地知道这种协调是如何工作的。快速解决方案-添加到一个map key={'key2${x}}},并使用这个`而不是这个',map返回一个数组,而不是单个span元素,因此两个map不会合并,因此不会共享同一个父元素。它们每个都有自己的父对象,这相当于一个片段。我对这到底是如何工作的缺乏正确的理解,但key实际上并不是实际DOM上的一个属性。我想你很清楚这一点,但我想这仍然是关键,这里没有双关语。React在内部处理两个元素数组,因此存在某种形式的作用域。@hotpink是的,我只是将其放在DOM上以说明我的观点。是的,可能有某种形式的作用域,你们是对的,我还在数组之前的示例中手动添加了一个跨度。但是要回答这个问题,你必须确切地知道这种协调是如何工作的。快速解决方案-添加到一个map key={'key2${x}}},并使用这个`而不是这个',map返回一个数组,而不是单个span元素,因此两个map不会合并,因此不会共享同一个父元素。它们都有自己的父对象,这相当于一个片段。