react的生命周期:
装载阶段
constructor
构造函数
可以理解为组件的第一个生命周期,⼀般会在这里初始化组件的内部状态(state), 如果在这里面要使用 this, 必须在super()之后,如果要在这里面使用props,那么需要把props做为参数传入。
在使用React.createClass()这种方式创建组件的时期,会有两个生命周期: getDefaultProps() // 直接使用static defaultProps = {}这种⽅式来创建 getInitialState() // 现在这个已经直接在constructor里使用this.state ={}这种方式来创建
componentWillMount**(组件将挂载)**
组件将要挂载,这个生命周期基本上没什么用,而且官方也说明了,将在 react 17这个版本之后废弃,如 果还想继续使用, 可以使用UNSAFE_componentWillMount来代替。
之前很多⼈总是觉得需要在这里做ajax请求,但这种做法是完全不对的
错觉:总是认为我在render前请求,那么render的时候就会直接使用请求的数据,但ajax是异步 的,不会直接更新。
react官方也说明,不要在这里做异步请求。
在react 新的版本里,采用了fiber算法,之前的版本是diff。 diff是同步渲染,fiber是异步渲染, 异步的渲染,有可能随时中断,那么componentWillMount就可能执行多次,由此可以想到ajax请 求也有可能会执行多次。
当然,这个生命周期,也是除了初始化之外,,惟一一个能够直接同步修改state的地方。
static getDerivedStateFromProps(获取从数据中延伸的数据)
这是react 16.3之后新增的一个生命周期,这是一个静态方法,静态方法没有this. 所以不能使用 setState, 需要return一个对象,这个对象就相当于setState里的参数。
常⽤于强制性的根据props来设置state
使用后 willMOunt会失效,在装置和更新阶段都会执行,可以用来修正state。
render
这⾥是合成虚拟dom, 可以理解为,在这⾥实际上都还没有真实的dom.
componentDidMount(组件已经挂载)
渲染真实的dom到浏览器,在这里才可以得到DOM。这个生命周期就是相当重要的一个生命周期, ajax请求一般都在这里进行。
更新阶段
分为两种情况,state改变和props改变,如果state改变,会直接用shouldComponentUpdate,如果 是props改变,会先走componentWillReceiveProps
componentWillReceiveProps**(组件将接收的数据)**
16.4之前,由于在更新阶段,没有static getDerivedStateFromProps这个周期,如果有根据props来生 成的state,就需要在这里再重新设置一次, 因为之前是在constructor里面根据props来初始化的state, constructor只会执行一次,所以,要在componentWillReceiveProps来修正state。在新的版本里, static getDerivedStateFromProps这个生命周期不管是在装载还是更新的时候都会触发。因为, componentWillReceiveProps也只会工作到react 17
shouldComponentUpdate**(需要改变组件吗)**
这个生命周期用于react的性能优化,接收两个参数(nextProps, nextState)通常会根据这两个参数和 this.state, this.props来进行比较,根据比较的结果来return true或者false, 如果return的是false,将不 会再执行后面的生命周期。 React.PureComponent就是在shouldComponentUpdate里做了浅比较。 如果要做深度比较(deep equal), 可以自己写递归(太麻烦),也可以直接使用odash。
componentWillUpdate**(组件将要改变)**
然并卵, 也是只到react 17
render
和mount阶段一样
componentDidUpdate (组件已经改变)
同componentDidMount, 当然这个会执行多次了。
销毁阶段
componentWillUnmount
组件将要销毁,这里一般可以用来清理定时器,解绑某些事件。