React 列表 & Keys

2023-11-17

列表 & Keys

列表

React 列表可以使用 JavaScriptmap() 方法来创建。如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React demo</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="example"></div>

<script type="text/babel">
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((numbers) =>
  <li>{numbers}</li>
);

ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('example')
);
</script>

</body>
</html>

页面效果:
在这里插入图片描述

但是,可以看到控制台有报错:
在这里插入图片描述

意思就是,每个数组或迭代器中的子元素应该有一个唯一的 “key” 值。

Keys

修改代码,给每个子元素加上唯一的 key 值:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React demo</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="example"></div>

<script type="text/babel">
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

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

</body>
</html>

当在 map() 方法的内部调用元素时,应该为每一个元素加上一个独一无二的 key,这样就不会报错啦。

总结:

  • Keys 可以在 DOM 中的某些元素被增加或删除的时候帮助 React 识别哪些元素发生了变化。因此,应当给数组中的每一个元素赋予一个确定的标识。
  • 一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串。通常,我们使用来自数据的 id 作为元素的 key
  • 当元素没有确定的 id 时,可以使用他的序列号索引 index 作为 key;如果列表可以重新排序,不建议使用索引来进行排序,因为这会导致渲染变得很慢。

keys提取组件

元素的 key 只有在它和它的兄弟节点对比时才有意义。

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

例如,下面的写法是错误的:

function ListItem(props) {
  const value = props.value;
  return (
    // 不需要在这里指定key:
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 元素的key应该在这里指定
    <ListItem value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

正确的写法:

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>
  );
}

key 的唯一性

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React demo</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="example"></div>

<script type="text/babel">
function Blog(props) {
  const titlebar = (
    <ul>
      {props.arr.map((item) =>
        <li key={item.id}>
          {item.title}
        </li>
      )}
    </ul>
  );
  const contentbar = props.arr.map((item) =>
    <div key={item.id}>
      <h1>{item.title}</h1>
      <p>{item.content}</p>
    </div>
  );
  return (
    <div>
      {titlebar}
      <hr />
      {contentbar}
    </div>
  );
}

const posts = [
  {id: 1, title: 'title 1', content: 'This is title 1!'},
  {id: 2, title: 'title 2', content: 'This is title 2!'}
];
ReactDOM.render(
  <Blog arr={posts} />,
  document.getElementById('example')
);
</script>

</body>
</html>

页面效果:
在这里插入图片描述

key 会作为给 React 的提示,但不会传递给组件。如果组件中需要使用和 key 相同的值,需要将其作为属性传递。如下:

  const contentbar = arr.map((item) =>
    <Post key={item.id} id={item.id}/>
  )

Post 组件可以读出 props.id,但是不能读出 props.key

在 jsx 中嵌入 map()

JSX 允许在大括号中嵌入任何表达式,可以在里面嵌入 map()

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

不过,如果一个 map() 嵌套了太多层级时,就应该提取出组件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React 列表 & Keys 的相关文章

  • 使用 javascript 调用 ViewComponent

    我有一个带有几个视图组件的网页 当我单击这些组件时 我会为其打开一个简单的编辑器 请参见下图 如果我编辑文本并按 Enter 键 我想重新渲染视图组件而不是孔页面 是否可以使用 javascript 调用视图组件来获得此行为 通过更新 您现
  • 从 DOM 中删除后,动态添加的 JavaScript 脚本会继续执行

    因此 我正在创建一个 SPA 并使用 AJAX 将 HTML 页面加载到我网站的索引页面中 问题是 当包含我的一个页面时 它似乎会徘 徊并执行其中的 JavaScript 代码 即使它随后从 DOM 中删除 索引 html 正文 div d
  • 在AWS S3中部署react-redux应用程序

    我在堆栈溢出中遇到了很多类似的问题one https stackoverflow com questions 16267339 s3 static website hosting route all paths to index html
  • ref scrollIntoView 不适用于反应上的平滑行为

    我正在创建一个组件 该组件将保存动态元素列表 出于样式原因 我需要将每个部分的标题保留在粘性导航菜单中 当用户上下滚动部分列表时 我需要应用样式规则 并将菜单导航中的同一部分带入视图 因此我尝试将scrollIntoView与菜单部分引用一
  • 如何从 URL 字符串中删除某些参数?

    我有这个var存储表示充满参数的 URL 的字符串 我正在使用 AngularJS 我不确定是否有任何有用的模块 或者可能使用纯 JavaScript 来删除不需要的 URL 参数而无需使用正则表达式 例如我需要删除 month 05并且
  • 一个 Next.js 路由中的两个不同子域

    我想使用构建一个新平台Next js https nextjs org React js https reactjs org and 反应路由器 https reacttraining com react router web guides
  • 代码点火器 JSON

    你好 我使用 codeigniter 然后我从控制器中的数据库中回显输出 然后在我的视图文件中执行以下操作 但它没有显示任何内容 S 我的模型文件 function forumList this gt db gt select oversk
  • WebDriver:更改事件未触发

    我有一个使用 KnockoutJS 的应用程序 我正在尝试编写一些测试表单的测试 如果您不了解 KnockoutJS 简单来说 它提供了从我的视图到我的数据模型的绑定 这意味着当我在输入字段中键入值时 我的基础对象会自动使用该输入字段值进行
  • 带有嵌入式 Ruby 的 Javascript:如何安全地将 ruby​​ 值分配给 javascript 变量

    我在页面的 javascript 块中有这一行 res foo 处理这种情况的最佳方法是什么 ruby var里面有单引号吗 否则会破坏 JavaScript 代码 我想我会用红宝石JSON http json org ruby var 上
  • t /= d 是什么意思? Python 和错误

    t current time b begInnIng value c change In value d duration def easeOutQuad swing function x t b c d alert jQuery easi
  • 正则表达式 - 避免表达式中出现字符串

    我正在尝试创建一个应该匹配以下情况的正则表达式 如果单词完全匹配 first second third 那么匹配应该失败 但如果它周围有任何字符 那么应该匹配该字符串 我还需要避免字符串中的某些字符集 如果这些字符是字符串的一部分 则匹配结
  • Rxjs 可观察等待直到满足某些条件

    我有以下重试逻辑来重试操作 对于单个请求来说它工作得很好 对于多个正在进行的请求 我想在重试之前等待现有的重试逻辑完成 handleError errors Observable
  • 对数字和字母元素的数组进行排序(自然排序)

    假设我有一个数组 var arr 1 5 ahsldk 10 55 3 2 7 8 1 2 75 abc huds 我尝试对其进行排序 我得到了类似的东西 1 1 10 2 2 3 5 55 7 75 8 abc ahsldk huds 注
  • 全局定义的 AngularJS 控制器和封装

    根据 AngularJS 的教程 控制器函数仅位于全局范围内 http docs angularjs org tutorial step 04 http docs angularjs org tutorial step 04 控制器函数本身
  • while 循环元素状态 cypress

    我有一个问题 我想单击一个按钮直到它消失 但次数可能会有所不同 所以我想检查可见性状态 当可见 true时单击按钮 当可见 false时结束测试 但问题是我不知道如何循环从获取元素到末尾的所有链 单击按钮一次 由于中断而停止 如果我删除中断
  • 运行 tsc(TypeScript 编译器)时如何复制 dist 或 build 文件夹中的 package.json

    我有一个 TypeScript React 组件 它使用package json文件 参见屏幕截图 然后我运行tsc为了在我的中将其转译为 es5dist文件夹但package json文件没有被复制 请注意 在屏幕截图中 我手动将其复制到
  • 地址更改时如何停止 Angular 重新加载

    我正在使用 Angular 的scrollTo and anchorScroll像这样 app controller TestCtrl function scope location anchorScroll scope scrollTo
  • Chrome Prerender 功能每次都会被取消

    我正在尝试 Chrome 中的预渲染功能 但是当我检查网络时 我可以看到任何链接的请求都被取消 我使用以下语法 我尝试了现场演示http prerender test appspot com http prerender test apps
  • 如何仅在第一次访问时弹出模态窗口

    我有一个模式窗口 当您访问某个页面时会弹出 访客必须选择我同意或我不同意 我需要一个漂亮的小 jquery 脚本 它会记住谁之前访问过该页面并同意 这样他们每次访问该页面时就不会弹出模式 有人可以推荐一个好的脚本来使用吗 这是代码 div
  • 从 Node.js 调用 execl、execle、execlp、execv、execvP 或 execvp 的方法

    POSIX 系统公开了一系列exec函数 允许人们将可能不同的东西加载到当前进程中 保留打开的文件描述符 进程标识符等 可以出于多种原因执行此操作 在我的情况下 这是引导 我想更改我自己的进程的命令行选项 然后在现有进程上重新加载它 这样就

随机推荐