react原理揭秘

318 阅读3分钟

setState()

首先setState()更新数据是异步更新数据,当你在调用setState时马上打印数据,数据还是上一次的

当调用两次setState时第一次修改数据,和第二次修改数据修改的初始值都是一样的,第二次修改的并不是第一次修改后的值

后面的setState不要依赖前前面的setState

多次调用setState只会触发一次render

推荐语法

setState((state,props)=>{
      return {
               修改数据
       }
})

这样还是异步的,但是可以拿到上一次更新以后的数据

setState() 第二个参数是一个回调,会在数据更新后立即执行,并且页面渲染后,所以也可以操作DOM,与componentDidUpdate类似,拿到的状态就是更新完成之后的

jsx语法转化过程

jsx语法是createElenmet()方法的语法糖(简化语法)

jsx是被babel/preset-react编译为createElement()方法

然后createElenmet()就会生成React元素

这里就要解释一下,React元素:是一个对象,用来描述你希望在屏幕上看到的内容

组件更新机制

父组件重新渲染时,也会重新渲染子组件。但只会渲染当前组件子树(当前组件及其所有子组件)

当某个组件发生更新,那么只会影响自己以及自己的后代组件更新

所以根组件更新之后,所有的状态都会更新

组件性能优化

减轻state

state只存储跟组件渲染相关的数据

不用做渲染的数据不要放在state中

如果数据跟渲染没有关系,但是在很多方法中用到,那就放在this中

避免不必要的重新渲染(父组件更新,不让子组件做不必要的更新)

使用钩子函数 shouldComponentUpdate(nextProps,nextState) 通过this.state可以拿到更新之前的state

作用:通过返回值决定是否重新渲染

需要注意:true重新渲染、false不重新渲染、必须有返回值

触发时机:更新阶段的钩子, 组件重新渲染前触发, render前触发

diff算法

在渲染渲染页面之前会生成虚拟DOM与真实DOM进行对比,对比的方法就diff算法

diff算法最小力度为标签,标签一样不替换,标签中的字元素不同只替换元素

虚拟DOM

作用:将一次渲染中的多次DOM操作整合成一次进行操作

这里就要说到key的作用

  • 官方:key是虚拟DOM对象的表示,在更新显示时key起着极其重要的作用

  • 细谈:当状态中的数据发生变化是,react会根据【新数据】生成【新的虚拟DOM】,随后React进行【新虚拟DOM】与【旧虚拟DOM】的diff比较

  • diff比较规则

    旧虚拟DOM中找到了与新虚拟DOM相同的key -> 若虚拟DOM中的内容没变,直接使用之前的真实DOM,若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

    旧虚拟DOM中未找到与新虚拟DOM相同的key -> 根据数据创建新的真实DOM,随后渲染到页面

用index作为key可能引发的问题

若对数据进行逆序操作,没有必要的DOM更新

例如:

往数据最前面添加元素的时候

一一对比发现key和对应的值不同了

则会让整个数据全部重新渲染

如果结构中还包括可输入DOM,还会产生错误的DOM更新

开发中为何使用id当key?

唯一性,类似身份证号码

虚拟DOM的真正价值不是在于性能, 而是将React脱离了浏览器环境的束缚

感谢阅读!!!