博主头像
<CodeEra />

心存敬畏 行有所止

React 生命周期钩子(新)

在 React 16.3 之后,React 引入了新的生命周期钩子,并对一些旧的生命周期钩子进行了废弃或重命名。新的生命周期钩子更加清晰和安全,同时也引入了 static getDerivedStateFromPropsgetSnapshotBeforeUpdate 等新的钩子。以下是 React 新生命周期钩子的详细说明:


1. 挂载阶段(Mounting)

挂载阶段是指组件被创建并插入到 DOM 中的过程。这个阶段涉及以下生命周期钩子:

  • constructor(props)

    • 调用时机:组件被创建时调用。
    • 作用:初始化组件的状态(this.state)和绑定事件处理函数。
    • 注意:在 constructor 中必须调用 super(props),否则 this.props 将会是 undefined
  • static getDerivedStateFromProps(props, state)

    • 调用时机:在组件挂载和更新时调用。
    • 作用:根据新的 props 和当前的 state 返回一个新的状态对象,或者返回 null 表示不需要更新状态。
    • 注意:这是一个静态方法,不能访问 this,通常用于在 props 变化时更新 state
  • render()

    • 调用时机:在组件挂载和更新时调用。
    • 作用:返回组件的 JSX 结构,描述组件应该如何渲染。
    • 注意render 必须是纯函数,不能在其中修改组件的状态或执行副作用。
  • componentDidMount()

    • 调用时机:在组件挂载到 DOM 之后调用。
    • 作用:可以在这里执行 DOM 操作、发起网络请求或设置定时器等。
    • 注意:这是执行副作用的理想位置,因为此时组件已经挂载到 DOM 中。

2. 更新阶段(Updating)

更新阶段是指组件的 propsstate 发生变化,导致组件重新渲染的过程。这个阶段涉及以下生命周期钩子:

  • static getDerivedStateFromProps(props, state)

    • 调用时机:在组件接收到新的 propsstate 时调用。
    • 作用:根据新的 props 和当前的 state 返回一个新的状态对象,或者返回 null 表示不需要更新状态。
    • 注意:这是一个静态方法,不能访问 this
  • shouldComponentUpdate(nextProps, nextState)

    • 调用时机:在组件接收到新的 propsstate 时调用。
    • 作用:决定组件是否需要重新渲染。返回 true 表示需要重新渲染,返回 false 表示不需要。
    • 注意:可以通过这个钩子优化性能,避免不必要的渲染。
  • render()

    • 调用时机:在组件更新时调用。
    • 作用:返回组件的 JSX 结构,描述组件应该如何重新渲染。
  • getSnapshotBeforeUpdate(prevProps, prevState)

    • 调用时机:在组件即将重新渲染之前调用。
    • 作用:可以在这里捕获 DOM 更新前的状态(如滚动位置),并将返回值传递给 componentDidUpdate
    • 注意:通常与 componentDidUpdate 配合使用。
  • componentDidUpdate(prevProps, prevState, snapshot)

    • 调用时机:在组件重新渲染之后调用。
    • 作用:可以在这里执行 DOM 操作、发起网络请求或更新状态等。
    • 注意:可以在这里比较 prevPropsprevState,以确定是否需要执行某些操作。

3. 卸载阶段(Unmounting)

卸载阶段是指组件从 DOM 中移除的过程。这个阶段涉及以下生命周期钩子:

  • componentWillUnmount()

    • 调用时机:在组件即将从 DOM 中移除之前调用。
    • 作用:可以在这里执行清理操作,如取消网络请求、清除定时器或移除事件监听器等。
    • 注意:这是执行清理操作的理想位置,因为此时组件即将被销毁。

4. 错误处理(Error Handling)

React 16 引入了错误边界(Error Boundaries)的概念,用于捕获子组件中的 JavaScript 错误,并显示备用 UI。错误处理涉及以下生命周期钩子:

  • static getDerivedStateFromError(error)

    • 调用时机:在子组件抛出错误时调用。
    • 作用:根据错误返回一个新的状态对象,用于渲染备用 UI。
    • 注意:这是一个静态方法,不能访问 this
  • componentDidCatch(error, info)

    • 调用时机:在子组件抛出错误时调用。
    • 作用:可以在这里记录错误信息或执行副作用。
    • 注意:错误边界只能捕获子组件中的错误,不能捕获自身抛出的错误。

5. 废弃的生命周期钩子

在 React 16.3 之后,以下生命周期钩子被标记为不推荐使用(UNSAFE_ 前缀):

  • componentWillMount → 使用 componentDidMountconstructor 替代。
  • componentWillReceiveProps → 使用 static getDerivedStateFromProps 替代。
  • componentWillUpdate → 使用 getSnapshotBeforeUpdatecomponentDidUpdate 替代。

6. 新生命周期钩子的执行顺序

以下是新生命周期钩子的典型执行顺序:

  1. 挂载阶段

    • constructor
    • static getDerivedStateFromProps
    • render
    • componentDidMount
  2. 更新阶段

    • static getDerivedStateFromProps
    • shouldComponentUpdate
    • render
    • getSnapshotBeforeUpdate
    • componentDidUpdate
  3. 卸载阶段

    • componentWillUnmount
  4. 错误处理

    • static getDerivedStateFromError
    • componentDidCatch

7. 总结

React 新生命周期钩子更加清晰和安全,废弃了一些容易导致问题的旧钩子,并引入了 static getDerivedStateFromPropsgetSnapshotBeforeUpdate 等新钩子。对于新项目,建议使用新的生命周期钩子,或者直接使用 React Hooks(如 useEffect)来管理组件的生命周期,因为它们提供了更简洁和灵活的方式来处理副作用和状态管理。

发表新评论