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脱离了浏览器环境的束缚
感谢阅读!!!