1.遍历

const numbers = [1, 2, 3, 4, 5];const listItems = numbers.map((number) =><li>{number}</li>
);ReactDOM.createRoot(document.getElementById('root')).render(<ul>{listItems}</ul>);

2.基础列表组件

function NumberList(props) {const numbers = props.numbers;const listItems = numbers.map((number) =><li>{number}</li>);return (<ul>{listItems}</ul>);
}const numbers = [1, 2, 3, 4, 5];ReactDOM.createRoot(document.getElementById('root')).render(<NumberList numbers={numbers}/>);

运行上记代码时,会发生下面的错误

意思是当你创建一个元素时,必须包括一个特殊的 key 属性

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.createRoot(document.getElementById('root')).render(<NumberList numbers={numbers}/>);

key 帮助 React 识别哪些元素改变了,比如被添加或删除

元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串

const todoItems = todos.map((todo) =><li key={todo.id}>{todo.text}</li>
);
function TodoList(props){const todos = props.todos;const todoItems = todos.map((todo) =><li key={todo.id}>{todo.text}</li>);console.log(todoItems);return (<ul>{todoItems}</ul>)
}const todos = [{id: 1,text: "a"},{id: 2,text: "b"},{id: 3,text: "c"}];ReactDOM.createRoot(document.getElementById('root')).render(<TodoList todos={todos}/>);

当元素没有确定 id 的时候,可以使用元素索引 index 作为 key

const todoItems = todos.map((todo, index) =>// Only do this if items have no stable IDs<li key={index}>{todo.text}</li>
);
function TodoList(props){const todos = props.todos;const todoItems = todos.map((todo, index) =>// Only do this if items have no stable(固定的) IDs<li key={index}>{todo.text}</li>);return (<ul>{todoItems}</ul>)
}const todos = [{text: "a"},{text: "b"},{text: "c"}];ReactDOM.createRoot(document.getElementById('root')).render(<TodoList todos={todos}/>);

注意:列表项目的顺序可能会变化,这时不建议使用索引来用作 key 值 ,可能会导致性能变差,甚至还可能引起组件状态的问题

key值的作用

它是一个特殊的属性,不是给开发者用的,而是给React自己用,有了key属性后,就可以与组件建立了一种对应关系,简单说,react利用key来识别组件。每个key 对应一个组件,相同的key react认为是同一个组件,这样后续相同的key对应组件都不会被创建

如果两个元素是相同的key,且满足第一点元素类型相同, 若元素属性有所变化,则React只更新组件对应的属性,这种情况下,性能开销会相对较小

在render函数执行的时候,新旧两个虚拟DOM会进行对比,如果两个元素有不同的key,那么在前后两次渲染中就会被认为是不同的元素,这时候旧的那个元素会被unmount,新的元素会被mount

错误案例:

function ListItem(props) {const value = props.value;return (<li key={value.toString()}>{value}</li>);
}function NumberList(props) {const numbers = props.numbers;const listItems = numbers.map((number) =><ListItem value={number} />);return (<ul>{listItems}</ul>);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.createRoot(document.getElementById('root')).render(<NumberList numbers={numbers} />);

错误原因分析:

元素的 key 只有放在就近的数组上下文中才有意义

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

key 只是在兄弟节点之间必须唯一

数组元素中使用的 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.createRoot(document.getElementById('root')).render(<Blog posts={posts} />);reportWebVitals();

注意点:key 会传递信息给 React ,但不会传递给使用的组件。如果组件中需要使用 key 属性的值,需要用其他属性名显式传递这个值:

function ListItem(props) {const value = props.value;return (<li key={value.toString()}>{value}</li>);
}function NumberList(props) {const numbers = props.numbers;return (<ul>{numbers.map((number) =><ListItem key={number.toString()}value={number} />)}</ul>);
}
const numbers = [1, 2, 3, 4, 5];ReactDOM.createRoot(document.getElementById('root')).render(<NumberList numbers={numbers} />);

React中文文档 8. 列表 Key相关推荐

  1. react中文文档、英文文档及JavaScript相关文档及web前端相关资料

    一. react中文文档 https://doc.react-china.org 二. react英文文档 https://reactjs.org 三.react Github https://git ...

  2. React中文文档之Thinking in React

    Thinking in React - 思考React 在我们看来,React是使用js来创建大的.速度快的web应用的首选方式.它已经在Facebook和Instagram表现的非常好. React ...

  3. React中文文档之Forms

    Forms - 表单 在React中,HTML表单元素同其他DOM元素,有点不同.因为表单元素天生具备一些内部的state状态.例如:下面的HTML表单接收一个名字: <form>Name ...

  4. React中文文档之Handling Events

    Handling Events - 事件处理 React元素的事件处理同DOM元素的事件处理非常相似. 有一些语法不同: 1.React事件使用 'camelCase-驼峰式' 命名,而不是 'low ...

  5. React中文文档之Conditional Rendering

    Conditional Rendering - 有条件的渲染 在React中,你可以创建唯一的组件,来封装你需要的行为.之后,你可以仅仅渲染它们中的一些,这取决于你应用的状态. React中的有条件的 ...

  6. React中文文档之introducing JSX

    introducing JSX 思考下面的变量声明: const element = <h1>Hello world!</h1>; 这个有趣的标签解析,既不是字符串,也不是HT ...

  7. React中文文档之State and Lifecycle

    state 和 生命周期 到目前为止,我们仅仅学习了一种方式来更新UI. 我们调用 'ReactDOM.render()' 来改变输出渲染: function tick() {const elemen ...

  8. React中文文档之Rendering Elements

    Rendering Elements - 渲染元素 元素是React应用的最小构建块 一个元素描述了你想要在屏幕上看到的内容: const element = <h1>Hello, wor ...

  9. React中文文档之Components and Props

    Components and Props - 组件和属性 组件允许你分隔UI为独立的.可重用的零件,每个零件是隔离的. 概念上,组件就像js的函数.它们接收任意的输入(被称为 'props'),并返回 ...

最新文章

  1. Windows Phone本地数据库(SQLCE):11、使用LINQ查询数据库(翻译) (转)
  2. 从0实现一个tiny-redux
  3. mysql 5.7 多实例主从_mysql-5.7.20源码安装 + 多实例 + 主从复制
  4. UPS技术的“前世今生”【基础篇.PPT】
  5. 基于享元记忆的 Boost.Flyweight 示例
  6. java大数据组件Zookeeper
  7. MySQL中文参考手册--8.MySQL教程--8.3 常用查询的例子
  8. 统计源期刊目录_护理核心期刊投稿最强攻略:期刊目录、投稿周期、发文倾向全在这里了!...
  9. JAVA中JDK环境变量配置
  10. 电子设计教程42:限流软启动电路
  11. Linux应用层例程7 CAN 应用编程基础
  12. cox生存分析-从基本概念到参数求解
  13. 实现jul 日志重定向到 slf4j
  14. 【目标跟踪】|STARK
  15. 循序渐进学爬虫:多线程+队列爬取豆瓣高分计算机类书籍 1
  16. 推荐 5 款私藏的优质 Chrome 插件
  17. baq在聊天中啥意思,Epicor 10在BPM工作流设计器中链接BAQ(避免自定义代码)
  18. 【Linux】文件查找、权限设置以及综合应用
  19. Ubuntu下连上网络开始学习啦
  20. 新款HTTP代理抓包工具Proxyman(界面美观、功能强大)

热门文章

  1. 阿里云ECS服务器环境搭建(2) —— ubuntu 16.04 安装中文输入法(搜狗输入法)
  2. 华为最新5G V2X高级使用案例曝光,未来交通是这样的!
  3. YOLOV5 6.0加入CA注意力机制(看了包会)
  4. DM数据库的启停以及数据库状态检查
  5. 单片机编程简易计算机的设计,简易计算器设计
  6. 解决QQ不能下载文件的问题
  7. 给RTL8111网卡固定MAC地址的一种方法
  8. 微信小程序 录像 录视频
  9. GIS——地图比例尺
  10. 博达网站服务器地址怎么查,路由器博达路由器配置经典教程