前言
渲染流程
- App根组件render函数通过jsx语法return了html标签元素,当然也可以包含react组件标签。
- render函数的运行实际上通过
React.createElement('div', config, children)
生成对应的reactComponent虚拟DOM - 首次渲染,根据虚拟DOM生成真实DOM
渲染生命周期:
constructer->render->componentDidMount
更新生命周期:
(shouldComponentUpdate)->render->(beforeComponentUpdate)->componentDidUpdate
更新流程
- 触发更新的条件一定是: 组件内部的props或者state发生改变
- 接着render函数重新执行-》生成新的虚拟DOM树-〉新旧虚拟DOM进行diff->层级比较计算出差异进行更新-》更新到真实DOM
更新中KEYS用法
render函数内性能优化
为什么需要render内性能优化?
假设有以下组件树结构
render () {
console.log('App render')
return (
<div>
<Home/>
<Recommand />
</div>
)
}
- 当App根组件内出现setState或者props变化,不管改变的那个值是否在子组件中用到了,三个组件内部的render都会执行,App render-> Home render-> Recmannd render
- 当APP内setState值和以前初始化的state值一样,也会造成三者render
这样做非常浪费性能,因为要重新生成虚拟DOM比对
解决方案
1、不太好的方案
SCU-shouldComponentUpdate
原理:
- 组件的shouldComponentUpdate生命周期返回true 执行render,返回false 不执行render。
- 该生命周期函数接受两个参数,nextProps,nextState,可根据即将更新的这2个值和当前state和props值比对,去判断return true/false
缺点:
- 类组件能实现功能,但是当state中属性太多,会导致光内部逻辑判断非常多,对开发同学很不友好
- 函数组件无法使用,因为没有生命周期
2、react实现的好方案
类组件 pureComponent
把类组件的继承由Component改为 PureComponent,这样内部自动实现了和外部数据不相干的组件不重新执行render
函数组件 memo
用memo包裹没有名字的函数,赋值给一个变量(即组件名字),并导出即可