返回介绍

Keys

发布于 2024-06-23 21:09:03 字数 4523 浏览 0 评论 0 收藏 0

Keys 可以在 DOM 中的某些元素被增加或删除的时候帮助 React 识别哪些元素发生了变化。因此你应当给数组中的每一个元素赋予一个确定的标识。

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);

一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串。通常,我们使用来自数据的 id 作为元素的 key:

const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);

当元素没有确定的 id 时,你可以使用他的序列号索引 index 作为 key

const todoItems = todos.map((todo, index) =>
  // Only do this if items have no stable IDs
  <li key={index}>
    {todo.text}
  </li>
);

如果列表项目的顺序可能会变化,我们不建议使用索引来用作键值,因为这样做会导致性能的负面影响,还可能引起组件状态问题。如果你想要了解更多,请点击 深度解析 key 的必要性 。如果你选择不指定显式的键值,那么 React 将默认使用索引用作为列表项目的键值。

这里有一篇文章 in-depth explanation about why keys are necessary ,要是你有兴趣了解更多的话。

用 keys 提取组件

元素的 key 只有放在其环绕数组的上下文中才有意义。

比方说,如果你提取出一个 ListItem 组件,你应该把 key 保存在数组中的这个 <ListItem /> 元素上,而不是放在 ListItem 组件中的 <li> 元素上。

function ListItem(props) {
  // 对啦!这里不需要指定 key:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 又对啦!key 应该在数组的上下文中被指定
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

在 CodePen 上试试。

一个好的大拇指法则:元素位于 map() 方法内时需要设置键属性。

键(key)只是在兄弟之间必须唯一

数组元素中使用的 key 在其兄弟之间应该是独一无二的。然而,它们不需要是全局唯一的。当我们生成两个不同的数组时,我们可以使用相同的键

function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {content}
    </div>
  );
}

const posts = [
  {id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
  {id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
  <Blog posts={posts} />,
  document.getElementById('root')
);

在 CodePen 上试试。

key 会作为给 React 的提示,但不会传递给你的组件。如果您的组件中需要使用和 key 相同的值,请用其他属性名显式传递这个值:

const content = posts.map((post) =>
  <Post
    key={post.id}
    id={post.id}
    title={post.title} />
);

上面例子中, Post 组件可以读出 props.id ,但是不能读出 props.key

在 jsx 中嵌入 map()

在上面的例子中,我们声明了一个单独的 listItems 变量并将其包含在 JSX 中

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

JSX 允许在大括号中嵌入任何表达式,所以我们可以在 map() 中这样使用:

function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />
      )}
    </ul>
  );
}

在 CodePen 上试试。

这么做有时可以使你的代码更清晰,但有时这种风格也会被滥用。就像在 JavaScript 中一样,何时需要为了可读性提取出一个变量,这完全取决于你。但请记住,如果一个 map() 嵌套了太多层级,那可能就是你 提取出组件 的一个好时机。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文