一、列表渲染
我们再react中如果渲染列表,一般使用map方法进行渲染
import React from "react";
export default class LearnJSX2 extends React.Component {
  state = {
    infos: [
      {
        name: "张三",
        age: 18,
      },
      {
        name: "李四",
        age: 20,
      },
      {
        name: "王五",
        age: 25,
      },
    ],
  };
  render() {
    return (
      <div>
        <div>
          {
            /**
             * 使用 map进行列表渲染
             * map返回要渲染的列表jsx
             *
             * 使用箭头函数 可以直接return 但是要注意加括号
             * 并且 括号内 只能有一个根元素
             */
            this.state.infos.map((item, index) => (
              // 循环的时候必须要在最上层的元素上加key
              <div key={index}>
                {item.name} -- {item.age}
              </div>
            ))
          }
        </div>
      </div>
    );
  }
}
二、为什么map的时候要加key
1、作用
key是react用来追踪哪些列表的元素被修改,被添加或者是被删除的辅助标示。在开发过程中我们需要保证某个元素的key在其同级元素中具有唯一性。
在react的diff算法中react会借助元素的key来判断该元素是最新创建的还是被移动而来的,从而减少不必要的元素渲染。除此之外,react还要根据key来判断元素与本地状态的关联关系。
2、注意
- key的值一定要和具体的元素一一对应
- 尽量不要用数组中的index来作为key的值
- 当我们在做数组遍历批量生成子节点时,切记同层级的每个子节点的key值不能重复且不会发改变,否则将会产生不可预估的bug
- key改变组件会重新渲染
2、为什么index不能作为key呢?
编写一个列表,点击列表中的每一项进行删除
使用index当做key
import React from "react";
export default class LearnJSX3 extends React.Component {
  state = {
    arr: ["a", "b", "c", "d"],
  };
  delItem(index) {
    this.state.arr.splice(index, 1);
    this.setState({
      arr: this.state.arr,
    });
  }
  render() {
    return (
      <div>
        <div>
          {/* 
            使用key当做下标
          */}
          {this.state.arr.map((item, index) => (
            <div onClick={() => this.delItem(index)} key={index}>
              {item}
            </div>
          ))}
        </div>
      </div>
    );
  }
}
这么乍一看,好像可以正常实现功能,但是我们通过浏览器的控制台检查列表的渲染后发现,我们删除了一个项,竟然连带着整个列表都进行了重新渲染!

使用item或者其它不会改变的项当做key
import React from "react";
export default class LearnJSX3 extends React.Component {
  state = {
    arr: ["a", "b", "c", "d"],
  };
  delItem(index) {
    this.state.arr.splice(index, 1);
    this.setState({
      arr: this.state.arr,
    });
  }
  render() {
    return (
      <div>
        <div>
          {/* 
            使用item当做下标
          */}
          {this.state.arr.map((item, index) => (
            <div onClick={() => this.delItem(index)} key={item}>
              {item}
            </div>
          ))}
        </div>
      </div>
    );
  }
}

原因
当我们用index做下标的时候,点击删除列表中的每一项,下标都会发生变化,如果用下标当做key就会触发dom重新渲染。如下图所示。
<!-- newVDom -->
<div>
    <div>b</div>  <!-- key==0 -->
    <div>c</div>  <!-- key==1 -->
    <div>d</div>  <!-- key==2 -->
</div>
<!--  oldVDom -->
<div>
    <div>a</div>  <!-- key==0 -->
    <div>b</div>  <!-- key==1 -->
    <div>c</div>  <!-- key==2 -->
    <div>d</div>  <!-- key==3 -->
</div>
 oldVDom -->
<div>
    <div>a</div>  <!-- key==0 -->
    <div>b</div>  <!-- key==1 -->
    <div>c</div>  <!-- key==2 -->
    <div>d</div>  <!-- key==3 -->
</div>


















