Skip to content

React16 生命周期 #14

@DelBlank

Description

@DelBlank

React15 组件的生命周期如图:

img

React16.3 之后组件的生命周期变为:

image

新生命周期废弃componentWillMountcomponentWillReceivePropscomponentWillUpdate 三个方法。取而代之的是两个新的周期函数:static getDerivedStateFromPropsgetSnapshotBeforeUpdate

从新生命周期的图中能看出,组件的生命周期分为三个阶段:挂载阶段(Mounting),更新阶段(Updating)及卸载阶段(Unmounting),每个阶段根据代码的执行顺序又可以分为

  • 渲染阶段(Render phase):渲染阶段涉及的周期函数全是纯函数,没有任何副作用。
  • 预提交阶段(Pre-commit phase):该阶段可以读取真实 DOM 节点。
  • 提交阶段(Commit phase):该阶段可以操作 DOM 节点并且执行有副作用的代码。

新老生命周期三阶段对比:

老生命周期 新生命周期
挂载阶段 constructor
componentWillMount
render
componentDidMount
constructor
static getDerivedStateFromProps
render
componentDidMount
更新阶段 componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
static getDerivedStateFromProps
shouldComponentUpdate
render
getSnapshotBeforeUpdate
componentDidUpdate
卸载阶段 componentWillUnmount componentWillUnmount

再看下新增的两个方法:

  • static getDerivedStateFromProps(props,state):它的主要作用是在 props 变化时衍生计算新的 state,与 componentWillReceiveProps 的差异在于:
static getDerivedStateFromProps(props, state) componentWillReceiveProps(nextProps)
静态方法,不能调用实例的 this 非静态方法,可以调用实例的 this
接收参数有两个 props (组件当前接收的最新参数)和 state(组件当前的内部状态) 接收参数只有 nextProps
根据该方法的返回值自动设置组件的 state 手动调用 setState 设置组件的 state
触发条件有挂载阶段构造函数执行之后,props changesetState()forceUpdate() 触发条件只有 props change

getDerivedStateFromProps 方法出现之前,componentWillReceiveProps 方法主要解决两个问题:根据 nextProps 计算 nextState根据 nextProps 触发新异步方法,引入 React16 新生命周期后,前一个问题可以放在 getDerivedStateFromProps 中解决,后一个问题被建议放到 componentDidUpdate 中去解决。React 官方希望开发者能够谨慎使用 getDerivedStateFromProps

在使用 static getDerivedStateFromPropscomponentWillReceiveProps 时,要注意两个反模式:无条件拷贝 propsstateprops 变化时清除 state。正确的解法参考完全受控组件使用 key 的非受控组件

  • getSnapshotBeforeUpdate(prevProps, prevState):该方法在 componentDidUpdate 之前被调用,该函数主要作用是在更新真实节点之前获取节点的信息,在一些特定场景下(如计算滚动条位置)比较有用。
  • static getDerivedStateFromError(error):除了上面两个新的周期函数,React16.6 又引入了一个新的生命周期。该生命周期的主要作用是捕获子组件抛出的错误,然后根据错误更新父组件的状态。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions