zoukankan      html  css  js  c++  java
  • react 列表渲染

    https://reactjs.org/docs/lists-and-keys.html#keys

    以下代码运行会报错:Warning: Each child in an array or iterator should have a unique 'key' prop.

    const arr = [<li>{numbers[0]}</li>,<li>{numbers[0]}</li>,<li>{numbers[1]}</li>]
    return (
        <ul>{arr}</ul>
    );

    改成这样子,就不会报错了:

      return (
        <ul>
          <li>{numbers[0]}</li>
          <li>{numbers[0]}</li>
          <li>{numbers[1]}</li> 
        </ul>
      );

    以上的区别是什么?

      当 渲染一个数组 的时候,必须要为数组中的单元设置一个key属性,这是react的要求。用于让react去跟踪数组元素的增加和删除、移动等,这是key唯一的作用。当元素从数组中读取出来时,react没办法直接跟踪,需要通过key。

    对key的要求

    要添加在数组item元素的根元素上,而且对于当前数组来说是唯一和稳定的,可以采用如下方式来生成id:

    var shortid = require('shortid');
    function createNewTodo(text) {
      return {
        completed: false,
        id: shortid.generate(),
        text
      }
    }

    key可以使用索引,但不推荐,因为这可能会使列表展示错误的数据,以下来演示一下:

    class List extends React.Component{
        constructor(props){
            super(props)
            this.state = {
                arr:[9,8,7]
            }
            this.changeArr = this.changeArr.bind(this);
        }
        changeArr(){
            this.setState((preState)=>{
                preState.arr.unshift(10);
                return {
                    arr:preState.arr
                }
            })
        }
        render(){
            return (
                <div>
                    <button onClick={this.changeArr}>change</button>
                    <ul>
                        {this.state.arr.map((item,index) =>
                            <li key={item}>
                                {item}  <input />
                            </li>
                        )}
                    </ul>
                </div>
            )
        }
    }

    在线运行:https://codepen.io/gaearon/pen/jrXYRR?editors=0011,以上input的作用是记录dom的状态,可以简单判断dom有没有被重新创建

    测试发现规律如下:

    不指定key,控制台出现warning,默认以index为key,显式指定key=index,则不报warning,但运行的效果和不指定一样,因为默认都是index为key【这和vue一致,都是默认“就地复用”,以上相同的测试对于vue结果一致】。

    当render的时候,对比前后两个虚拟dom,发现key一样则复用这个dom,即刷新后,被复用dom的状态依然和render前一样【以上的input输入的值会保留】

    如果key中出现相同的值(假设为5),则第一个key为5的dom会复用之前的dom,而后一个key为5的则创建新的dom

    key的作用是跟踪数组中dom的变化,

    我提出的问题:

      https://stackoverflow.com/questions/48032286/the-detail-in-react-list-render

      https://segmentfault.com/q/1010000012649420

    补充vue的测试代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <button @click="this.change">change</button>
            <div v-for="(item ,index) in arr" :key="item"> {{item}}
                <input type="text">
            </div>
        </div>
    </body>
    <script>
        const vm = new Vue({
            el:"#root",
            data:{
                arr:[1,2,3],
            },
            methods:{
                change:function(){
                    vm.arr.unshift(1)
                }
            }
        });
    </script>
    </html>

     ps:vue1中出现相同元素,如[1,2,1],会报错,vue2以后不会了,指定的key只能是原始类型,而不能是对象类型

  • 相关阅读:
    寒假学习10
    寒假学习9
    寒假学习8
    寒假学期7
    寒假学习6
    寒假学习5
    寒假学习4
    Notification通知栏的使用
    Service的使用
    BroadcastReceive的使用
  • 原文地址:https://www.cnblogs.com/hellohello/p/8150400.html
Copyright © 2011-2022 走看看