代码之家  ›  专栏  ›  技术社区  ›  cbdeveloper

列表中的React元素的最佳键是什么?

  •  0
  • cbdeveloper  · 技术社区  · 6 年前

    想象一下我有这么多东西

    fullList = [
      {label: "item A", id="itemA", someBool: true}, 
      {label: "item B", id="itemB", someBool: true}, 
      {label: "item C", id="itemC", someBool: true}, 
      {label: "item D", id="itemD", someBool: false}, 
      {label: "item E", id="itemE", someBool: false},
    ];
    

    但我不会在屏幕上显示完整的列表。我根据一些过滤值过滤它,并呈现一个过滤列表。

    用户与过滤器交互,并将根据他/她选择的过滤器看到不同的过滤列表。

    那我有了 按键有两个选项:

    const filteredList = fullList.filter((item) => item.someBool === true);
    
    const filteredListItems = filteredList.map((item,index) => 
      <Item_UI_Component
        key={item.id}          // OPTION #1 - THIS IS ONLY POSSIBLE IF THE FULL LIST CONTAINS id's
        key={index}            // OPTION #2 - THIS IS ALWAYS POSSIBLE
        ...SOME OTHER PROPS
      />
    );
    

    问题

    这两种方法的实际区别是什么?我和他们中的任何一个一起得到或失去什么吗?如果我给元素一个如选项1所示的通用唯一键,React会优化什么吗?或者在这两种情况下它的行为都一样吗?

    选项1:

    • 关键是一个唯一的ID,不管是什么
    • 相同的元素在每个渲染上总是得到相同的ID

    选项2:

    • 钥匙总是独一无二的 filteredList ,但同一元素可以使用不同于上次渲染的键重新渲染。

    注: 如果不设置任何键,将收到警告:

    警告: 列表中的每个子项都应具有唯一的“键”属性。见 https://reactjs.org/docs/lists-and-keys.html#keys 更多信息。

    1 回复  |  直到 6 年前
        1
  •  1
  •   TKoL    6 年前

    官方文件:

    https://reactjs.org/docs/lists-and-keys.html

    当您没有呈现项的稳定id时,您可以使用项索引作为最后的手段。如果项的顺序可能更改,我们不建议对键使用索引。这可能会对性能产生负面影响,并可能导致组件状态问题。

    正如我在评论中所说:

    原因是,如果您的过滤器更改了,并且现在位于索引2的项与以前位于索引2的项不同,则存在一个非常真实的风险,即React将被混淆,而不是在那里呈现一个新组件,它只会改变它发送组件的道具——而且它可能根本不会在视觉上更新,这取决于您如何对它进行编码。

    我个人以前用索引作为键肯定有问题

        2
  •  0
  •   SuleymanSah    6 年前

    如果您的数据具有自然唯一的id,则应将其用作密钥。

    如果数据没有自然id,则在满足以下所有条件时,可以使用索引作为键:

    1. 列表和项是静态的,不计算也不更改
    2. 列表中的项目没有ID
    3. 列表从不重新排序或筛选。

    Source

    如果数据没有自然的id,并且需要更改列表,则可以向模型中添加新的id属性,或者对内容的某些部分进行哈希处理以生成密钥。密钥只需在其兄弟之间是唯一的,而不是全局唯一的。

    Source