React文档(九)list和key
首先,我们回顾一下在js里如何转换数组。
给出下面的代码,我们使用map()函数来获取一个数组的numbers然后将值变成两倍大。我们分配新数组由map()返回:
- const numbers = [1, 2, 3, 4, 5];
- const doubled = numbers.map((number) => number * 2);
- console.log(doubled);
这段代码在控制台输出[2, 4, 6, 8 ,10]。
在React里,把数组转变成一系列元素也是一样的。
渲染多个组件
通过使用花括号,你可以创建一组元素,并且把它们包含在JSX里。
下面,我们对numbers数组使用map()函数。为每一项返回一个<li>元素。最后,我们将元素数组处理的结果存为listItems:
- const numbers = [1, 2, 3, 4, 5];
- const listItems = numbers.map((number) =>
- <li>{number}</li>
- );
我们将整个listItems数组放进一个<ul>元素里,然后把它渲染到DOM里:
- ReactDOM.render(
- <ul>{listItems}</ul>,
- document.getElementById('root')
- );
这段代码展示了一个1到5的数字列表。
基础列表组件
通常你会将列表渲染到一个组件里。
我们可以重构上一个例子到一个组件里,这个组件接受一个number数组,输出一个无序的元素列表。
- 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.render(
- <NumberList numbers={numbers} />,
- document.getElementById('root')
- );
当你运行这段代码 ,你会看到一个警告,一个key需要提供给列表。“key”是一个特殊的字符串属性当你创建列表元素的时候你所需要的属性。在下一章节会讨论为什么这个属性很重要。
让我们在numbers.map()里分配一个key给列表元素来修复没有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.render(
- <NumberList numbers={numbers} />,
- document.getElementById('root')
- );
keys
key帮助React鉴别哪一项发生了改变,添加了,或者移除了。key应该添加在数组里的元素身上作为一个稳定的特性。(我靠,这个是不是和html里的自定义属性很像啊)
- 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,也许会用数据项的索引作为key:
- const todoItems = todos.map((todo, index) =>
- // Only do this if items have no stable IDs
- <li key={index}>
- {todo.text}
- </li>
- );
如果数据项可以重排序我们不建议使用索引作为key,因为那样会降低速度。也许你可以读一读这篇深入理解为何key很重要。
依据key提取组件
元素的key只有在它和它的兄弟节点对比时才有意义。
举个例子,如果你提取了一个ListItem组件,你应该保持key在数组里的<listItem />元素里而不是在ListItem的<li>元素里。
例子:错误的用法
- function ListItem(props) {
- const value = props.value;
- return (
- // Wrong! There is no need to specify the key here:
- <li key={value.toString()}>
- {value}
- </li>
- );
- }
- function NumberList(props) {
- const numbers = props.numbers;
- const listItems = numbers.map((number) =>
- // Wrong! The key should have been specified here:
- <ListItem value={number} />
- );
- return (
- <ul>
- {listItems}
- </ul>
- );
- }
- const numbers = [1, 2, 3, 4, 5];
- ReactDOM.render(
- <NumberList numbers={numbers} />,
- document.getElementById('root')
- );
例子:正确的用法
- function ListItem(props) {
- // Correct! There is no need to specify the key here:
- return <li>{props.value}</li>;
- }
- function NumberList(props) {
- const numbers = props.numbers;
- const listItems = numbers.map((number) =>
- // Correct! Key should be specified inside the array.
- <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')
- );
好的做法就是在map()方法调用里面的元素需要key。
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.render(
- <Blog posts={posts} />,
- document.getElementById('root')
- );
key对React来说就是一个提示但是它们没有传递给你的组件。如果你需要同样的值在你的组件里,那就换一个不同的名字把它作为props传递:
- const content = posts.map((post) =>
- <Post
- key={post.id}
- id={post.id}
- title={post.title} />
- );
通过上面的例子,Post组件可以读取props.id这个属性,而不是props.key。
在JSX中嵌入map()
- function NumberList(props) {
- const numbers = props.numbers;
- const listItems = numbers.map((number) =>
- <ListItem key={number.toString()}
- value={number} />
- );
- return (
- <ul>
- {listItems}
- </ul>
- );
- }
JSX允许嵌入任何表达式在花括号里因此我们能够内嵌map()直接到ul里面:
- function NumberList(props) {
- const numbers = props.numbers;
- return (
- <ul>
- {numbers.map((number) =>
- <ListItem key={number.toString()}
- value={number} />
- )}
- </ul>
- );
- }
React文档(九)list和key的更多相关文章
- React文档(十三)思考React
在我们的看来,React是使用js创建大型快速网站应用的首要方法.它在Facebook和Instagram的使用已经为我们展现了它自己. React的一个很好的地方就在于当你创建应用的时候它使你思考如 ...
- React文档(二十四)高阶组件
高阶组件(HOC)是React里的高级技术为了应对重用组件的逻辑.HOCs本质上不是React API的一部分.它是从React的组合性质中显露出来的模式. 具体来说,一个高阶组件就是一个获取一个组件 ...
- react文档demo实现输入展示搜索结果列表
文档页面地址:https://doc.react-china.org/docs/thinking-in-react.html 该文档只给了具体实现思路,下面是我实现的代码. 初学react,如果有写的 ...
- CYQ.Data 轻量数据层之路 优雅V1.4 现世 附API帮助文档(九)
继上一版本V1.3版本发布到现在,时隔N天了:[V1.3版本开源见:CYQ.Data 轻量数据层之路 华丽V1.3版本 框架开源] N天的时间,根据各路网友的反映及自身的想法,继续修改优化着本框架,力 ...
- React文档(一)安装
React是一个灵活的可以用于各种不同项目的框架,你可以用它来写新应用,你也可以逐步将它引进已有的代码库而不用重写整个项目. 试用React 如果你想玩一玩React,那么就去CodePen上试一试. ...
- React文档(十九)不使用ES6
通常你会将一个React组件定义成一个普通的js类: class Greeting extends React.Component { render() { return <h1>Hell ...
- React文档(二十一)协调
React提供了一个声明式地API因此你不用担心每一次更新什么东西改变了.这使得开发应用变得简单,但是这个东西在React中如何实现的并不是很明显.这篇文章会解释我们在React的算法中所做的选择以便 ...
- React文档(十六)refs和DOM
Refs 提供了一种方式,用于访问在 render 方法中创建的 DOM 节点或 React 元素. 在标准的React数据流中,props是使得父组件和子组件之间交互的唯一方式.你通过props重新 ...
- React文档(十五)使用propTypes进行类型检查
注意: React.PropTypes 自 React v15.5 起已弃用.请使用 prop-types 库代替. 随着你的应用的开发,你会使用类型检查的方法来捕获很多bug.对于一些应用,你可以使 ...
随机推荐
- asp.net mvc 简单实现一个账号只能在一个地方登录
原理: 假设用户在机器A登陆后, 这时用户再次在机器B登陆,会以当前会话的SessionID作为键,用户id作为值,插入dictionary集合中,集合再保存在application(保存在服务器 ...
- NIO学习资料
五大IO模型 https://jiges.github.io/2018/02/07/%E4%BA%94%E5%A4%A7IO%E6%A8%A1%E5%9E%8B/ Getting started wi ...
- ajax 显示,删除,批量删除,修改反填功能实现
1.页面代码 <body> <h1>显示所有员工信息</h1> <input id="Button1" type="button ...
- word之高级
1.更正拼写和语法错误. 2.取消自动编号. 3.添加删除水印. 4.段落设置首行缩进2个字符. 需要先选中需要设置的段落 5.文字覆盖. insert键切换插入与改写功能.修改word状态栏上的改写 ...
- KVM 通过virsh console连入虚拟机
新安装一台虚拟机后,是无法通过virsh console 命令连入虚拟机中的,这时我们需要开启虚拟机的console功能. 一.添加ttyS0的许可,允许root登陆 [root@localhost ...
- Twisted简介
Twisted是用Python实现的基于事件驱动的网络引擎框架,Twisted支持许多常见的传输及应用层协议,包括TCP.UDP.SSL/TLS.HTTP.IMAP.SSH.IRC以及FTP.就像Py ...
- java微信开发之地图定位
页面代码: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEnc ...
- LeetCode #002# Add Two Numbers(js描述)
索引 思路1:基本加法规则 思路2:移花接木法... 问题描述:https://leetcode.com/problems/add-two-numbers/ 思路1:基本加法规则 根据小学学的基本加法 ...
- PHP防止网页快速刷新+代理ip访问
前几天网站收到了一些CC攻击,比较郁闷...这里分享一下,防止网页自动刷新的方法以及阻止代理IP访问网站的方法,代码是分开的,两个功能,需要那个用那个,可以自定义时间间隔,这个代码不止可以防CC攻击, ...
- java web 的 几种跨域方式