内容简介:组件的生命周期分为3个阶段:挂载阶段、更新阶段、卸载阶段,每个阶段都包含相应的生命周期方法,对于生命周期,我们需要注意以下几点:
组件的生命周期分为3个阶段:挂载阶段、更新阶段、卸载阶段,每个阶段都包含相应的生命周期方法,对于生命周期,我们需要注意以下几点:
-
每个阶段执行了哪些生命周期以及它们的执行顺序(包括初始化、组件props改变引起的更新,组件state改变引起的更新,组件销毁四种情况下执行的是哪些生命周期)
-
每个生命周期内可以干哪些事情
-
哪些生命周期可以发起数据请求
-
哪些生命周期可以setState,哪些不可以
概念
-
constructor
是ES6对类的默认方法,主要用来初始化state
-
componentWillMount()
用于组件挂之前,全局只调用一次,如果在这个钩子里可以setState
,render
后可以看到更新后的state
,不会触发重复渲染。该生命周期可以发起请求,并setState
;这是服务端渲染中唯一调用的钩子; 通常情况下,推荐用constructor()
方法代替; -
render()
用于渲染组件,render
必须定义,用来渲染dom
,不要在render
里面修改state
,会触发死循环导致栈溢出。 -
componentDidMount
用于组件挂载完成后,全局只调用一次,可以在这里使用refs
获取真实的dom
元素。该钩子内也可以发起异步请求,并在异步请求后可以进行setState
。 -
componentWillReceiveProps(nextProps)
用于在props
即将变化之前,props
发生变化以及父组件重新渲染时都会触发该生命周期,在该生命周期可以通过参数nextProps
获取变化后的props
参数,通过this.props访问之前的props
。该生命周期内可以进行setState
。 -
shouldComponentUpdate(nextProps,nextState)
用来确定是否重新渲染,组件挂载之后,每次调用setState
后都会调用shouldComponentUpdate
判断是否需要重新渲染组件。默认返回true
,需要重新render
,返回false
则不触发渲染。在一些比较复杂的应用中,有一些数据的改变并不影响界面展示,可以在这里做判断,优化渲染效率。 -
componentWillupdate(nextProps,nextState)
,shouldComponentUpdate(nextProps,nextState)
返回true
或者调用forceUpdate
之后,componentWillUpdate
会被调用,不能在钩子中setState
,会触发重复渲染。 -
componentDidUpdate()
用于完成组件渲染,除了首次调用componentDidMount
,其他render
结束之后都是调用componentDidupdate
。该钩子内setState
有可能会触发重复渲染,需要自行判断,否则会进入死循环。 -
componentWillUnmount()
用于组件即将被卸载,一般componentDidMount
里面注册的事件需要在这里删除
阶段
组件初始化
componentWillMount
-> render
-> componentDidMount
组件更新 – props change
componentWillReceiveProps
-> shouldComponentUpdate
-> componentWillUpdate
-> componentDidUpdate
组件更新 – state change
shoudlComponentUpdate
-> componentWillUpdate
-> componentDidUpdate
组件卸载或销毁
componentWillUnmount
应用场景
数据请求的时机
对于组件所需的初始数据,最合适的地方,是在 componentDidMount
方法中,进行数据请求,这个时候,组件完成挂载,其代表的DOM已经挂载到页面的DOM树上,即使获取到的数据需要直接操作 DOM
节点,这个时候也是绝对安全的。有些人还习惯在 constructor
或者 componentWillMount
中,进行数据请求,认为这样可以更快的获取到数据,但它们相比 componentDidMount
的执行时间,提前的时间实在是太微乎其微了。另外,当进行服务器渲染时, componentWillMount
是会被调用两次的,一次在服务器端,一次在客户端,这时候就会导致额外的请求发生。
组件进行数据请求的另一种场景:由父组件的更新导致组件的props发生变化,如果组件的数据请求依赖props,组件就需要重新进行数据请求。例如,新闻详情组件NewsDetail,在获取新闻详情数据时,需要传递新闻的id作为参数给服务器端,当NewsDetail已经处于挂载状态时,如果点击其他新闻,NewsDetail的componentDidMount并不会重新调用,因而componentDidMount中进行新闻详情数据请求的方法也不会再次执行。这时候,应该在componentWillReceiveProps中,进行数据请求:
componentWillReceiveProps(nextProps) { if(this.props.newId !== nextProps.newsId) { fetchNewsDetailById(nextProps.newsId) // 根据最新的新闻id,请求新闻详情数据 } } 复制代码
如果进行数据请求的时机是由页面上的交互行为触发的,例如,点击查询按钮后,查询数据,这时只需要在查询按钮的事件监听函数中,执行数据请求即可,这种情况一般是不会有疑问的。
setState的时机
组件的生命周期方法众多,哪些方法中可以调用setState更新组件状态?哪些方法中不可以呢?
-
可以的方法
componentWillMount、componentDidMount、componentWillReceiveProps、componentDidUpdate
这里有几个注意点:
- componentWillMount 中 同步 调用setState不会导致组件进行额外的渲染,组件经历的生命周期方法依次是componentWillMount -> render -> componentDidMount,组件并不会因为componentWillMount中的setState调用再次进行更新操作。如果是 异步 调用setState,组件是会进行额外的更新操作。不过实际场景中很少在componentWillMount中调用setState,一般可以通过直接在constructor中定义state的方式代替。
- 一般情况下,当调用setState后,组件会执行一次更新过程,componentWillReceiveProps等更新阶段的方法会再次被调用,但如果在componentWillReceiveProps中调用setState,并不会额外导致一次新的更新过程,也就是说,当前的更新过程结束后,componentWillReceiveProps等更新阶段的方法 不会 再被调用一次。(注意,这里仍然指 同步 调用setState,如果是异步调用,则会导致组件再次进行渲染)
- componentDidUpdate中调用setState要格外小心,在setState前必须有条件判断,只有满足了相应条件,才setState,否组组件会不断执行更新过程,进入死循环。因为setState会导致新一次的组件更新,组件更新完成后,componentDidUpdate被调用,又继续setState,死循环就产生了。
-
不可以的方法
其他生命周期方法都不能调用setState,主要原因有两个:
- 产生死循环。例如,shouldComponentUpdate、componentWillUpdate 和 render 中调用setState,组件本次的更新还没有执行完成,又会进入新一轮的更新,导致不断循环更新,进入死循环。
- 无意义。componentWillUnmount 调用时,组件即将被卸载,setState是为了更新组件,在一个即将卸载的组件上更新state显然是无意义的。实际上,在componentWillUnmount中调用setState也是会抛出异常的。
新版本的生命周期
react v16.3删掉以下三个生命周期
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
新增两个生命周期
- static getDerivedStateFromProps
- getSnapshotBeforeUpdate
static getDerivedStateFromProps
- 触发时间:在组件构建之后(虚拟dom之后,实际dom挂载之前) ,以及每次获取新的props之后。
- 每次接收新的props之后都会返回一个对象作为新的state,返回null则说明不需要更新state.
- 配合componentDidUpdate,可以覆盖componentWillReceiveProps的所有用法
class Example extends React.Component { static getDerivedStateFromProps(nextProps, prevState) { // 没错,这是一个static } } 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
锋利的jQuery
单东林、张晓菲、魏然 / 人民邮电出版社 / 2012-7-1 / 49.00元
《锋利的jQuery(第2版)》循序渐进地对jQuery的各种函数和方法调用进行了介绍,读者可以系统地掌握jQuery的选择器、DOM操作、事件和动画、AJAX应用、插件、jQuery Mobile、jQuery各个版本变化、jQuery性能优化和技巧等知识点,并结合每个章节后面的案例演示进行练习,达到掌握核心知识点的目的。 为使读者更好地进行开发实践,《锋利的jQuery(第2版)》的第8......一起来看看 《锋利的jQuery》 这本书的介绍吧!