React 16.3+ 生命周期
16.3版本向我们介绍了一些新的生命周期函数,他们将会替代已存在的生命周期函数并提供更好的React异步支持。本文基于之前的文章的更新,因此将会聚焦于新的生命周期函数而不是所有的生命周期函数。
static getDerivedStateFromProps(nextProps, prevState)
这个新的函数主要致力于确保在需要state和props的时候是同步的,并致力于替换componentWillReceiveProps
函数。这个函数将会在组件更新被调用同时也包括更新,就在constructor
之后,所以你不再需要用constructor来根据props初始化state了。强烈不建议做有副作用的操作。
getSnapshotBeforeUpdate(prevProps, prevState)
另外两个新函数,也被叫做"pre-commit phase"(预提期),将在Virtual DOM的变化影响到DOM之前被调用。如果你想读取当前DOM state将会非常有用。
即使这个函数并不是static,也建议返回一个值,而不是更新component。返回的值将会作为第三个参数传给componentDidUpdate
函数。
弃用的函数
下列的函数将会被标记为废弃并被重命名:
- componentWillReceiveProps ——UNSAFE_componentWillReceiveProps
- componentWillUpdate ——UNSAFE_componentWillUpdate
你将会在主版本中看到关于废弃的warning,并且方法将会被在17.0中移除(重命名的方法将会保留)
新的React生命周期总结如下图:
关于其他生命周期
constructor构造函数
constructor是基于OOP的,在新的对象被创建时这个函数都将会被调用。当我们的类继承与其他含有构造函数的类时,调用一个特殊的函数super将会非常重要。调用这个函数将会调用父类的构造函数来初始化自身,这就是为什么我们需要在调用super后才能获取到this.props的原因。
componentWillMount不再建议使用
可以做
- 通过
this.setState
更新state; - 在SSR(服务端渲染)时,执行具有副作用的函数(譬如:ajax)。
不可以做 - 在客户端执行具有副作用的函数。(译者注:原文为cause side-effects (AJAX calls etc.) in case of server-side-rendering only,但在SSR时ajax操作则会在服务端和客户端执行两次,了解更多看这里
componentWillReceiveProps(nextProps)不再建议使用
shouldComponentUpdate(nextProps , nextState , nextContext)
当props、state或context改变时,所有的React类都将会重新渲染他们自身。如果重渲染这个组件计算繁杂或是基于表现原因不建议时,将能通过这个函数决定是否重渲染。返回false
将会阻止重渲染,返回’true’将不会进行阻止。
不可以做
- 调用具有副作用的函数,ajax;
- 调用
this.setState
。
componentWillUpdate(nextProps, nextState)不再建议使用
componentDidUpdate(prevProps, prevState, prevContext)
这个方法将会在每次render
完成之后被调用。因为这个方法在每个重渲染生命周期中只会被调用一次,因此建议在进行一些会产生副作用的函数(ajax)。
可以做
- ajax操作。
不可以做
- 调用
this.setState
,会引起重渲染。
componentDidCatch(errorString , errorInfo)
这个生命周期方法能够相应自组件的事件,特别是对于任何没有被捕获的错误发生在自组件时。因此你可以在父元素中收集到这些错误并设置错误信息返回正确的信息或者记录在日志中返回给系统。
componentDidCatch(errorString, errorInfo) {
this.setState({
error: errorString
});
ErrorLoggingTool.log(errorInfo);
}
render() {
if(this.state.error) return <ShowErrorMessage error={this.state.error} />
return (
// render normal component output
);
}
- errorString——error调用
.toString()
方法后的值; - errorInfo——一个拥有
componentStack
组件调用栈的对象,能够追溯到error在哪里发生。
componentDidMount
这个方法在整个生命周期中只会被调用一次。
可以做
- ajax操作。
不可以做 - 调用
this.setState
因为会引起重渲染。
componentWillUnmount
利用这个方法清理组件所使用的各种计数器(setTimeout, setInterval),sockets或者是不再需要的表现。