一、RN组件的生命周期
概要
组件的生命周期描述了其从生成到消亡所经历的一系列状态。深入理解组件的生命周期及相关回调函数,可以使开发工作更加合理化,更是优化渲染性能的关键。
组件生命周期大概可以分为三个阶段:
第一阶段:组件的第一次绘制阶段,完成组件的加载和初始化。
第二阶段:组件的运行和交互阶段,处理用户交互、接收事件、更新界面等。
第三阶段:组件卸载消亡阶段,做一些清除定时器等清理工作。
生命周期流程,如下图(源自网络)所示:
组件生命周期流程图回调函数
回调函数 | 含义 | 调用次数 | 可否setState | 应用场景 |
---|---|---|---|---|
getDefaultProps | 获得组件默认属性 | 1 | 否 | 在组件类创建时调用一次,返回值被缓存下来,若父组件没有给某个prop赋值,则相应的属性将会合并到this.props |
getInitialState | 获得组件初始化状态 | 1 | 否 | 在组件挂载之前调用一次,返回值将会作为 this.state 的初始值 |
componentWillMount | 组件将要加载 | 1 | 是 | 业务相关的初始化操作、设置组件初始状态等 |
render | 组件渲染 | >=1 | 否 | 组件渲染具体的实现,包括一些逻辑判断,根据最新数据显示组件的最新状态 |
componentDidMount | 组件已经加载完成 | 1 | 是 | 与其他JS框架交互,如设置计时器、发起网络请求等 |
componentWillReceiveProps | 组件将要收到新属性 | >=0 | 是 | 根据接收到的新属性,执行后续操作,如更新组件状态、开启/关闭动画、发起网络请求等 |
shouldComponentUpdate | 是否需要更新组件 | >=0 | 否 | 当组件接收到新的属性和状态改变时,均会触发此函数。若返回true,往后执行;若返回false,不更新组件,进入等待状态。可做逻辑判断返回不同的值 |
componentWillUpdate | 组件将要更新 | >=0 | 否 | 做一些在更新界面之前要做的事情。此函数之后,就会调用render()来更新界面 |
componentDidUpdate | 组件更新完毕 | >=0 | 否 | 做一些组件更新完毕后的收尾工作 |
componentWillUnmount | 组件将要卸载 | 1 | 否 | 组件卸载后的一些清理工作,如取消定时器任务、结束动画、移除监听器、清除reducer数据等 |
二、痛点
1、从另一个页面pop回当前页面,没有相应的回调函数,无法在该时机做相应处理。
案例:从A页面push到B页面,一番操作之后,回到A页面,根据业务需求,需要请求网络数据刷新A页面展示。
解决方案:在恰当的时机,如B页面中的某个按钮被点击或B页面销毁时,调用A页面中的函数,请求接口刷新A页面数据。
缺憾:此类情况比较隐蔽,开发、测试阶段不易被发现,容易造成bug。
三、疑点
1、网络请求操作为什么一般要写在componentDidMount中,而不是constructor或者componentWillMount中?
- 在componentDidMount中,�组件已经渲染完成,处于稳定状态,在发出请求之前没有任何的等待。
- 在constructor或componentWillMount中发起网络请求,会阻碍组件的实例化和渲染。
- 在componentWillMount中调用setState,不会触发组件的重新渲染。
四、注意点
1、没有componentDidUnmount这一回调函数!
2、在componentWillMount、componentWillReceiveProps中调用setState方法更新组件状态,不会造成额外的render调用。
(待续...)
网友评论