React学习之列表运用(七)

对于列表其实也就是数组,我们可以用数组的map函数对数组集体进行公操作,如下:

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);

会对数组中的每一个元素执行乘 2 操作然后保存在doubled数组中。

接下我们就要介绍React数组元素或者说是列表元素的运用了

1.视图多重组件

通过上面的写法,我们就可以写出如下例子:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}li>
);

通过数组的map构造多重JSX语句,然后通过

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

语句就可以更新到视图中

在上一个例子的基础上我们就可以开发出通过数目来控制JSX语句的组件,有点像是JAVAWEBJSTLforEach的运用

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, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

必须为每一项增加一个key属性,这个属性不会更新到视图中,而是React对它进行管理,接下来,会讲解为什么要用key属性来处理

2.React中的key

React中的key会用来识别数组中的哪一个元素改变了,或者是增加了新的元素又或者是删除了数组中的元素,Reactkey来为每一个元素标记一个唯一的标识,以便进行更新处理。

如果你的列表使用的是一个对象数组,并且对象中有该对象的唯一标识,就可以这么做:

const todoItems = todos.map((obj) =>
  <li key={obj.id}>
    {obj.text}
  li>
);

如果没有的话,可以用数组的索引来当做临时的key进行标识

const todoItems = todos.map((obj, index) =>
  // 仅仅在没有唯一标识的情况下才用,属于备用方案
  
  • {obj.text} </li> );
  • 当然,官方强烈的建议不要使用索引来作为唯一标识,因为一旦重新进行排序,那么索引值就会更换,而如果每个对象都有自己的唯一标识的话则不会出现这样的问题,这会引起性能下降。

    这里只是简单的说明一下key的必要性,后续会有博客讲述为什么一定要有个key,有什么具体的好处。

    3.扩展组件上的key

    虽然我没有深入解释key的作用,但是可以明确一点的就是key的存在只是为了更好的处理数据,让上下文更有意义,举个简单的例子。

    就上面说到的例子,我们使用了一个ListItem组件,但是你是愿意保存他们的key来处理他们,还是愿意保存每一个li元素处理他们呢,很明显,用key更省内存,更好管理。

    一个不好的样例:

    function ListItem(props) {
      const value = props.value;
      return (
        // 这里其实是不需要key的,因为不是列表元素
        
  • {value} </li> ); } function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => //而这里却需要key因为它才是真正的列表元素 > ); 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
        
      );
      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的值。

    下一篇博客讲ReactForms表单的应用

    你可能感兴趣的:(React,React学习)