React学习之diff算法

发布时间 2023-10-12 10:46:17作者: 一米五怎么你了

1. 前言

找到了一篇特别好的笔记——diff

2. 验证diff

<!DOCTYPE html>
<html lang="en">
  <head>
    <style>
      .box {
        width: 300px;
        height: 150px;
        overflow: auto;
        background-color: skyblue;
      }
      .news {
        height: 30px;
      }
    </style>
  </head>
  <body>
    <div id="test1"></div>

    <!-- render 函数的执行结果就是 vdom,也就是 React Element 的实例 -->
    <!-- 页面状态有更新时,根据 key 对比同层级虚拟 dom,如果发生变化则增删改真实 dom -->
    <!-- 同层级:span 内的 input 输入内容也不会重新生成真实 dom -->

    <script type="text/babel">
      class Time extends React.Component {
        state = {
          date: new Date(),
        };

        render() {
          return (
            <div>
              <h1>hello</h1>
              <input type="text" name="" id="" />
              <br />
              <br />
              <span>
                现在是:{this.state.date.toTimeString()}&nbsp;
                <input type="text" name="" id="" />
              </span>
            </div>
          );
        }
        // componentDidMount ==> diffing ==> render
        componentDidMount() {
          setInterval(() => {
            this.setState({ date: new Date() });
          }, 1000);
        }
      }

      ReactDOM.render(<Time />, document.getElementById('test1'));
    </script>
  </body>
</html>

diff

3. key的作用

<!DOCTYPE html>
<html lang="en">
  <body>
    <div id="test1"></div>
    <script type="text/babel">
      class Time extends React.Component {
        state = {
          per: [
            { name: '小野', age: 18, id: 1 },
            { name: '友树', age: 19, id: 2 },
          ],
        };

        render() {
          return (
            <div>
              <h1>おはようございます</h1>
              <button onClick={this.add}>添加砂糖</button>
              <div
                ref={(c) => {
                  this.box = c;
                }}
              >
                {this.state.per.map((p, index) => {
                  return (
                    <p key={index}>
                      {p.name}
                      {p.age}
                    </p>
                  );
                })}
              </div>
            </div>
          );
        }
        componentDidMount() {
          setInterval(() => {}, 1000);
        }
        add = () => {
          const { per } = this.state;
          const newPer = { name: '砂糖', age: 20, id: per.length + 1 };
          this.setState({ per: [newPer, ...per] });
        };
      }

      ReactDOM.render(<Time />, document.getElementById('test1'));
    </script>
  </body>
</html>

3.1 key是index

初始数据:

{ name: '小野', age: 18, id: 1 },
{ name: '友树', age: 19, id: 2 },

初始虚拟dom:

<p key={1}>
  小野18
</p>
<p key={2}>
  友树19
</p>

更新数据:

{ name: '砂糖', age: 20, id:3 },
{ name: '小野', age: 18, id: 1 },
{ name: '友树', age: 19, id: 2 },

更新虚拟dom:

<p key={1}>
  砂糖20
</p>
<p key={2}>
  小野18
</p>
<p key={3}>
  友树19
</p>

新旧虚拟dom对比,三个节点全都需要生成 true dom

3.2 key是id

初始数据:

{ name: '小野', age: 18, id: 1 },
{ name: '友树', age: 19, id: 2 },

初始虚拟dom:

<p key={1}>
  小野18
</p>
<p key={2}>
  友树19
</p>

更新数据:

{ name: '砂糖', age: 20, id:3 },
{ name: '小野', age: 18, id: 1 },
{ name: '友树', age: 19, id: 2 },

更新虚拟dom:

<p key={3}>
  砂糖20
</p>
<p key={1}>
  小野18
</p>
<p key={2}>
  友树19
</p>

新旧虚拟dom对比,1、2不变;仅3不存在,生成 true dom