React中文文档 8. 列表 Key
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相关推荐
- react中文文档、英文文档及JavaScript相关文档及web前端相关资料
一. react中文文档 https://doc.react-china.org 二. react英文文档 https://reactjs.org 三.react Github https://git ...
- React中文文档之Thinking in React
Thinking in React - 思考React 在我们看来,React是使用js来创建大的.速度快的web应用的首选方式.它已经在Facebook和Instagram表现的非常好. React ...
- React中文文档之Forms
Forms - 表单 在React中,HTML表单元素同其他DOM元素,有点不同.因为表单元素天生具备一些内部的state状态.例如:下面的HTML表单接收一个名字: <form>Name ...
- React中文文档之Handling Events
Handling Events - 事件处理 React元素的事件处理同DOM元素的事件处理非常相似. 有一些语法不同: 1.React事件使用 'camelCase-驼峰式' 命名,而不是 'low ...
- React中文文档之Conditional Rendering
Conditional Rendering - 有条件的渲染 在React中,你可以创建唯一的组件,来封装你需要的行为.之后,你可以仅仅渲染它们中的一些,这取决于你应用的状态. React中的有条件的 ...
- React中文文档之introducing JSX
introducing JSX 思考下面的变量声明: const element = <h1>Hello world!</h1>; 这个有趣的标签解析,既不是字符串,也不是HT ...
- React中文文档之State and Lifecycle
state 和 生命周期 到目前为止,我们仅仅学习了一种方式来更新UI. 我们调用 'ReactDOM.render()' 来改变输出渲染: function tick() {const elemen ...
- React中文文档之Rendering Elements
Rendering Elements - 渲染元素 元素是React应用的最小构建块 一个元素描述了你想要在屏幕上看到的内容: const element = <h1>Hello, wor ...
- React中文文档之Components and Props
Components and Props - 组件和属性 组件允许你分隔UI为独立的.可重用的零件,每个零件是隔离的. 概念上,组件就像js的函数.它们接收任意的输入(被称为 'props'),并返回 ...
最新文章
- Windows Phone本地数据库(SQLCE):11、使用LINQ查询数据库(翻译) (转)
- 从0实现一个tiny-redux
- mysql 5.7 多实例主从_mysql-5.7.20源码安装 + 多实例 + 主从复制
- UPS技术的“前世今生”【基础篇.PPT】
- 基于享元记忆的 Boost.Flyweight 示例
- java大数据组件Zookeeper
- MySQL中文参考手册--8.MySQL教程--8.3 常用查询的例子
- 统计源期刊目录_护理核心期刊投稿最强攻略:期刊目录、投稿周期、发文倾向全在这里了!...
- JAVA中JDK环境变量配置
- 电子设计教程42:限流软启动电路
- Linux应用层例程7 CAN 应用编程基础
- cox生存分析-从基本概念到参数求解
- 实现jul 日志重定向到 slf4j
- 【目标跟踪】|STARK
- 循序渐进学爬虫:多线程+队列爬取豆瓣高分计算机类书籍 1
- 推荐 5 款私藏的优质 Chrome 插件
- baq在聊天中啥意思,Epicor 10在BPM工作流设计器中链接BAQ(避免自定义代码)
- 【Linux】文件查找、权限设置以及综合应用
- Ubuntu下连上网络开始学习啦
- 新款HTTP代理抓包工具Proxyman(界面美观、功能强大)