代码之家  ›  专栏  ›  技术社区  ›  Robo Robok

key={i}和key={`foo-${i}`之间有什么区别吗?

  •  1
  • Robo Robok  · 技术社区  · 2 年前

    我正在读一本名为《反应》的高级书 React食谱 。出于某种原因,作者使用了 key 带前缀,如下所示:

    <div>
        {state.items.map((s, i) => (
            <div key={`square-${i}`}>
                {s}
            </div>
        ))}
    </div>
    

    我一直在看 钥匙 以这种方式构建,它总是让我感到惊讶,尤其是来自一位资深作家。据我所知,这和 key={i}

    当我开始使用React时,一些不太先进的React开发人员告诉我,当你嵌套列表时,这很有用,比如:

    <div>
        {state.items.map((s, i) => (
            <div key={`square-${i}`}>
                {s.map(f, j) => (
                    <div key={`foo-${j}`}>
                        {f}
                    </div>
                )}
            </div>
        ))}
    </div>
    

    但是,这也是无用的,因为键的唯一性是有作用域的,对吧?因此,不同级别或不同列表中的键不需要是唯一的。

    也许会有 一些 如果我的清单由两种或两种以上的东西组成,比如这样:

    <div key={`${item.type}-${i}`}>
    

    但除此之外,为什么有人会用基于索引的键来代替索引呢?

    0 回复  |  直到 2 年前
        1
  •  1
  •   Robo Robok    2 年前

    我相信人们之所以开始添加前缀,是因为他们错误地假设了树中的唯一性是如何工作的:

    键的作用域为同级。您可以在组件树上/下使用相同的键,但不能从侧面使用。请注意,尽管这与DOM树本身没有直接关系,但与反应组件树有关。

    数组类型react child有一个“父”,因此键可以在“兄弟”之间重复(技术上不是兄弟,因为它们有这个“数组父”,在DOM树中是透明的)。

    以下代码有效,不会触发任何警告。 The related react-dom code can be found here.

        <parent key="unique">
          <sibling key="must" />
          <sibling key="be" />
          <sibling key="unique">
            <child key="unique" />
          </sibling>
        </parent>
    
      <div>
        {['a', 'b', 'c', 'd', 'e'].map((letter, idx) => (
          <span key={idx}>{letter}</span>
        ))}
        {['a', 'b', 'c', 'd', 'e'].map((letter, idx) => (
          <span key={idx}>{letter}</span>
        ))}
      </div>
    

    如果数据是“静态”的并且永远不会更改,那么使用索引作为关键方法是非常好和安全的,否则可能会出现渲染问题和/或性能问题。

        2
  •  1
  •   Shubham Waje    2 年前

    使用 foo-${i} 而不是 i 是多余的并且行为相同。

    因为,不建议将索引用于关键道具,无论它们是单独使用还是在字符串插值中使用。

    虽然前缀不变 index 无论何时从数组中添加或删除项,都将发生更改,并且 foo-0 不等于 foo-1 。在这种情况下,react将重新渲染项目,因为上一个关键道具与新道具不匹配。

        3
  •  -1
  •   principiorum    2 年前

    如果您的列表数据顺序可能发生更改,react官方文档不建议对密钥使用索引。我认为作者知道这一点,并为键创建前缀,使其成为字符串,而不仅仅是数字。检查文档中的密钥 here