有关React面试

137 阅读3分钟

生命周期

初始化阶段

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确定