生命周期
初始化阶段
constructor
componentWillUnmount:组件被渲染到页面之前触发,可以开启定时器,向服务器发送请求
render:组件渲染
componentDidMount:组件在已经被渲染到页面后触发:此时页面中有了真正的DOM的元素,可以进行相关的dom的操作
运行中阶段
componentWillReceiveProps():组件接收到属性时触发
shouldComponentUpdate():当组件接收到新属性,或者组件的状态发生改变时触发,组件首次渲染时并不会触发(一个react需要更新一个小组件时,很可能需要父组件更新自己的状态,而一个父组件的重新更新会造成它旗下所有的子组件重新render()方法,形成新的虚拟dom,再用diff算法对新旧虚拟dom进行结构和属性的比较,决定组件是否需要重新渲染)
componentWillUpdate():组件即将更新时触发
componentDidUpdate():组件被更新完成后触发。页面中产生了新的DOM元素,可以进行DOM操作
销毁
componentWillUnmount():组件被销毁时触发,可以清理定时器
react将dom抽象为虚拟dom,通过新旧虚拟dom这两个对象的差异(diff算法),最终只把变化的部分重新渲染。提高渲染效率的过程;
Diff算法
当你实际开发使用react的时候,某个时间点render()函数创建了一颗React元素树,也就模拟一个虚拟dom树,
在下一个state或者props更新的时候,render()函数将创建一颗新的React元素树,也就模拟了一个新的虚拟dom树
Tree Diff
将新旧两颗虚拟dom树,按照层级对应的关系,从头到尾遍历一遍,就能找到哪些元素是需要更新的。
react组件划分
UI组价负责UI的呈现,容器组件负责管理数据和逻辑;两者通过react-redux提供的connect方法联系起来。
为什么虚拟dom会提高性能
虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了不必要的dom操作,从而提高性能。
diff算法
把树形结构按照层级分解,只比较同级元素。
给列表结构的每个同源添加唯一的key属性,方便比较。
react优化
代码层面的优化:
shouldComponentUpdate(判断是否需要调用render方法重新描绘dom)和PureComponent,避免过多render function
不要直接改变setState数据,每次返回一个新的值,不要改变原来的值;
将props和state摊平,只传递component需要的props
代码体积的优化:
使用生产版本;
使用动态import,懒加载react组件;
使用babel-plugin-import优化业务组件的引入,实现按需加载;
使用key来帮助react识别列表中所有子组件的最小变化;
组件封装
扁平化设计数据,用纯组件,减少不必要的render,命名规范,写好对外接口,考虑健壮性,按需加载,高内聚,低耦合。
props和state:
同:
都会引发render的重新渲染
都可以自身设定初始值
异:
初始值:state来源getInitialState(constructor)函数,props来源于父组件或getDefaultProps
修改方式:只能setState,不能由父组件;props只能由父组件修改
对子组件:props是一个父组件传递给子组件的数据流。可以一直传递到子孙组件。state代表的是一个组件内部自身的状态,只能在自身组建中存在
Redux
action:用户触发的一个普通对象
reducer:根据action操作来做出不同的数据响应,返回一个新的state
store值由reducer确定