My App

动态key生成

动态key生成

在上一个模块中,我们学习了 React keys。当使用 .map 遍历数据时,我们需要为每个 React 元素提供一个唯一的 key 属性,以便 React 知道在渲染之间触发哪些 DOM 操作。

在之前的例子中,我们的数据方便地为每个项目提供了唯一的标记,我们能够使用这些标记:

const inventory = [
  {
    id: "abc123",
    name: "Soft-boiled egg press",
  },
  {
    id: "def456",
    name: "Hello Kitty toothbrush",
  },
];
 
// We can use the `id` field in our iterations:
inventory.map((item) => <ShopItem key={item.id} item={item} />);

但是如果我们的数据没有我们可以使用的唯一标记呢?

实际上,这是开发者最常问的一个问题。React 对每个项目都需要一个唯一的值,但我们并不总是有这个值!

让我们通过一个例子来探索。

贴纸

在下面的沙盒中,您可以点击生成随机贴纸:

核心逻辑已完成,但我们在控制台中收到了一个关键警告!让我们来修复它。

我将详细讲解这段代码是如何工作的,以及我们如何解决这个问题,但我鼓励你花几分钟自己动手尝试一下,看看你是否能理解发生了什么,并提出任何解决方案。

目标是通过动态生成每个贴纸的key来解决关键警告问题。

import StickerPad from './StickerPad';

function App() {
  return (
    <>
      <p>Click around to add stickers!</p>
      <StickerPad />
    </>
  );
}

export default App;

这段代码相当复杂。我们来谈谈它,看看我们如何解决关键警告:

这是视频中的最终代码:

function StickerPad() {
  const [stickers, setStickers] = React.useState([]);
 
  return (
    <button
      className={styles.wrapper}
      onClick={(event) => {
        const stickerData = getSticker();
        const newSticker = {
          ...stickerData,
          x: event.clientX,
          y: event.clientY,
          // Come up with a unique value for this sticker.
          id: crypto.randomUUID(),
        };
 
        const nextStickers = [...stickers, newSticker];
        setStickers(nextStickers);
      }}
    >
      {stickers.map((sticker) => (
        <img
          // Use that previously-created unique value
          // for the key:
          key={sticker.id}
          className={styles.sticker}
          src={sticker.src}
          alt={sticker.alt}
          style={{
            left: sticker.x,
            top: sticker.y,
            width: sticker.width,
            height: sticker.height,
          }}
        />
      ))}
    </button>
  );
}

换一种方式解决了吗?

如果你尝试了解决这个问题,很可能你会得出一个不同的解决方案。你的解决方案可能甚至比我想出的方案简单得多!

事实证明,许多看似简单的解决方案在某些情况下有相当大的缺点:它们可能导致性能问题或故障的用户界面错误。

在下一课中,我们将深入探讨两种常见的替代解决方案,并准确了解那些风险是什么。

On this page