React生命周期
react
生命周期可以从广义分为三个阶段,即挂载
、渲染
、卸载
。在这个过程中提供有很多生命周期钩子函数,在不同生命周期可以被调用。
挂载过程
当组件实力被创建并且被插入DOM中时,生命周期如下:
-
constructor()
构造函数 一般不可以调用setState
方法,只绑定初始状态-
组件挂载之前会调用构造函数
-
为子类实现构造函数时候,在构造函数内调用
super(props)
constructor(props) { super(props); }
-
通过在构造函数内使用
this.state
对象初始化内部的state
-
在给state赋值初始值时候避免将
props
赋值给state
,这是一个常见的错误
-
-
static getDerivedStateFromProps(props,state)
从props
中获取衍生的状态- 调用
render
方法之前调用 - 并且在初始化、更新阶段都会被调用
- 返回一个对象更新
state
,如果返回null
则不更新
- 调用
-
componentWillMount()
组件即将挂载 在新的生命周期中已经废除(谨慎使用) -
render()
渲染函数 -
componentDidMount()
组件挂载完成后,立即调用
下述方法即将过时谨慎使用:
UNSAFE_componentWillMount()
更新过程
当组件的props
或者state
发生变化时,组件生命周期如下:
-
compontentWillReceiveProps(nextProps)
组件即将接收props
阶段 -
static getDerivedStateFromProps(props,state)
获取新的状态 -
shouldCompontentUpdate(nextProps,nextState)
判断是否应该更新- 会在组件渲染之前被调用,返回值默认为true
- 首次渲染使用
forceUpdate()
时不会调用该方法 - 返回值
true
更新false
不更新 - 默认
state
每次发生变化组件都会重新渲染 - 如果考虑性能优化可以使用内置的
PureComponent
组件,PureComponent
会对props
和state
进行浅层次的比较,并且减少不必要的更新 - 如果
shouldComponentUpdate()
返回false
,将不会调用compoentWillUpdate()
,render()
和componentDidUpdate()
,并且返回false
仍然可能导致组件重新渲染
-
componentWillUpdate(nextProps,nextState)
- 当组件接收到新的
props
和state
时,会在渲染之前调用 - 初始渲染不会调用
- 不能在此方法中调用
this.setState
,也不能进行其他操作出发组件更新
- 当组件接收到新的
-
render()
-
getSnapshotBeforeUpdate(prevProps,prevState)
获取快照- 他的返回值将作为
componentDidUpdate()
的第三个参数 - 否则此参数为
undefined
- 他的返回值将作为
-
compontentDidUpdate(pervProps,prevState,snapshot)
-
会在更新结束之后立即被调用
-
首次渲染不会执行
-
当组件更新后可以对DOM进行操作
-
可以在该钩子函数中调用
setState
,但必须包裹在一个条件语句中不然会导致死循环componentDidUpdate(prevProps) { // 典型用法(不要忘记比较 props): if (this.props.userID !== prevProps.userID) { this.fetchData(this.props.userID); } }
-
下述方法即将过时,在新代码中应该避免使用:
UNSAFE_componentWillUpdate(nextProps,nextState)
UNSAFE_compontentWillReceiveProps(nextProps)
卸载过程
当组件从DOM中移除时,会调用以下钩子函数:
componentWillUnmount()
- 会在组件卸载之前调用
- 可以用作清理操作,例如清除timer、解绑事件,取消网络请求或者清除在
componentDidMount()
中创建的订阅 - 不能在此钩子函数中调用
setState
,因为组件永远不会被重新渲染
错误处理
当渲染,生命周期或者构造函数中抛出错误时,会调用以下钩子函数:
-
static getDerivedStateFromError(error)
-
后代组件抛出错误时候调用
-
返回一个值更新state
class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { // 更新 state 使下一次渲染可以显降级 UI return { hasError: true }; } render() { if (this.state.hasError) { // 你可以渲染任何自定义的降级 UI return <h1>Something went wrong.</h1>; } return this.props.children; } }
-
-
componentDidCatch(error, info)
-
后代组件抛出错误时候调用
-
error 抛出的错误
-
info 带有componentStack key的对象,包含引发错误的错误栈信息
-
允许支持副作用
lass ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { // 更新 state 使下一次渲染可以显示降级 UI return { hasError: true }; } componentDidCatch(error, info) { // "组件堆栈" 例子: // in ComponentThatThrows (created by App) // in ErrorBoundary (created by App) // in div (created by App) // in App logComponentStackToMyService(info.componentStack); } render() { if (this.state.hasError) { // 你可以渲染任何自定义的降级 UI return <h1>Something went wrong.</h1>; } return this.props.children; } }
-