对于列表其实也就是数组,我们可以用数组的map
函数对数组集体进行公操作,如下:
const numbers = [1,2,3,4,5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);
会对数组中的每一个元素执行乘
doubled
数组中。
接下我们就要介绍React
数组元素或者说是列表元素的运用了
1.视图多重组件
通过上面的写法,我们就可以写出如下例子:
const numbers = [1,5];
const listItems = numbers.map((number) =>
<li>{number}</li> );
通过数组的map
构造多重JSX
语句,然后通过
ReactDOM.render(
<ul>{listItems}</ul>,document.getElementById('root') );
语句就可以更新到视图中
在上一个例子的基础上我们就可以开发出通过数目来控制JSX
语句的组件,有点像是JAVAWEB
中JSTL
的forEach
的运用
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
去获取数据
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number}> {number} </li> ); return ( <ul>{listItems}</ul> ); } const numbers = [1,document.getElementById('root') );
必须为每一项增加一个key
属性,这个属性不会更新到视图中,而是React
对它进行管理,接下来,会讲解为什么要用key
属性来处理
2.React
中的key
React
中的key
会用来识别数组中的哪一个元素改变了,或者是增加了新的元素又或者是删除了数组中的元素,React
用key
来为每一个元素标记一个唯一的标识,以便进行更新处理。
如果你的列表使用的是一个对象数组,并且对象中有该对象的唯一标识,就可以这么做:
const todoItems = todos.map((obj) =>
<li key={obj.id}> {obj.text} </li> );
如果没有的话,可以用数组的索引来当做临时的key
进行标识
const todoItems = todos.map((obj,index) =>
// 仅仅在没有唯一标识的情况下才用,属于备用方案
<li key={index}>
{obj.text}
</li> );
当然,官方强烈的建议不要使用索引来作为唯一标识,因为一旦重新进行排序,那么索引值就会更换,而如果每个对象都有自己的唯一标识的话则不会出现这样的问题,这会引起性能下降。
这里只是简单的说明一下key
的必要性,后续会有博客讲述为什么一定要有个key
,有什么具体的好处。
3.扩展组件上的key
虽然我没有深入解释key
的作用,但是可以明确一点的就是key
的存在只是为了更好的处理数据,让上下文更有意义,举个简单的例子。
就上面说到的例子,我们使用了一个ListItem
组件,但是你是愿意保存他们的key
来处理他们,还是愿意保存每一个li
元素处理他们呢,很明显,用key
更省内存,更好管理。
一个不好的样例:
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> ); }
4.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> ); }
key
是专门为React
服务的,但是它不会传递给你的组件,也就是说,在组件中,你无法通过props.key
来获取它的值,但是它又绑定到了组件中,作为组件的属性而存在,然而,你无法通过this.key
,或者是通过参数获取它,它是React
特殊处理的。
如果你想获得key
的值只能另外设置一个值,然后通过props
属性对象获取key的值,如下:
const content = posts.map((post) =>
<Post key={post.id} id={post.id} title={post.title} /> );
另外标识一个id
属性来传递key
的值。