首页 > 解决方案 > 如何提供不变的唯一键来列出 React 中的项目?

问题描述

我正在尝试制作一个突出显示新更改字符的输入组件。为了实现这一点,我使输入元素透明,并在其下创建了一个绝对位置的 div,具有相同的字体大小。在该 div 中,我使用输入字符串的每个字符呈现跨度列表。为了跨度,我应用了 3 秒的动画,将其颜色从红色(突出显示)更改为黑色(正常)。
现在要使列表正常运行,我需要将一个键传递给每个列表项以唯一标识每个列表项,以便仅突出显示最新输入的字符,其余字符保持不变。

我试过的

  1. 使用索引作为键。
    只要我在最后插入文本就可以正常工作,但是当在所有后续元素的索引之间插入任何文本时,它们都会被更改,因此它们都会被更新并因此突出显示

  2. 使用字符作为键。
    因为只要任何字符重复,我们就只有 26 个字符 a 对两个不同的列表项具有相同的键,而且它的行为再次很奇怪

  3. 使用字符和上下文作为键(即,ch + arr[index+1] + arr[index-1] etc..) ,
    但是当涉及到类似的模式(例如“aaaaa”等)时,它的表现出乎意料。

  4. 使用随机数/id 生成器(uuid 等)/new Date().getTime()。
    但是一旦元素更新,渲染函数就会被调用并且所有列表项都会收到全新的键,所以它们都会更新

  5. 使用父组件中的计数器来计算输入字段中更改的总数,并将该数字作为键分配给新添加的字符组件。
    我不知道如何实现它,因为为此我需要检查元素是否还没有键分配新号码,否则保留旧号码。

有没有办法根据每个列表项的创建时间为每个列表项提供新键(唯一),以便我只能突出显示更改的元素?

class Input extends Component {
  render() {
    let elems = null;
    let str = Array.from(this.props.value);
    elems = str.map((ch, i, arr) => (
      <span key={ch + arr[i - 1]} className="ch"> // .ch has animation to change color from red to black
        {ch}
      </span>
    ));
    return (
      <div className="fancyText">
        <input
          type={this.props.type}
          value={this.props.value}
          placeholder={this.props.placeholder}
          onChange={this.props.onChange} 
        /> // this one is transparent
        <div className="highlighted"> // this is visible
            {elems}
        </div>
      </div>
    );
  }
}

这是沙盒链接*

标签: javascriptreactjslistkey

解决方案


为了完成您的需要,您可以使用一个简单的npm 包,名为uuid. 在类组件中首先导入它。

import { v4 as uuidv4 } from 'uuid';

然后你必须为你要重用的组件的第一个父标签分配唯一的 id。

<span key={uuidv4()} className="ch">
    {ch}
  </span>

如果您有自定义密钥,则可以像这样将其与 uuid 一起使用,

 <span key={uuidv4(YOUR_CUSTOM_KEY)} className="ch">
    {ch}
  </span>

希望这对您有所帮助。


推荐阅读