React 生命周期钩子(新)
在 React 16.3 之后,React 引入了新的生命周期钩子,并对一些旧的生命周期钩子进行了废弃或重命名。新的生命周期钩子更加清晰和安全,同时也引入了 static getDerivedStateFromProps 和 getSnapshotBeforeUpdate 等新的钩子。以下是 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)
更新阶段是指组件的 props 或 state 发生变化,导致组件重新渲染的过程。这个阶段涉及以下生命周期钩子:
static getDerivedStateFromProps(props, state)- 调用时机:在组件接收到新的
props或state时调用。 - 作用:根据新的
props和当前的state返回一个新的状态对象,或者返回null表示不需要更新状态。 - 注意:这是一个静态方法,不能访问
this。
- 调用时机:在组件接收到新的
shouldComponentUpdate(nextProps, nextState)- 调用时机:在组件接收到新的
props或state时调用。 - 作用:决定组件是否需要重新渲染。返回
true表示需要重新渲染,返回false表示不需要。 - 注意:可以通过这个钩子优化性能,避免不必要的渲染。
- 调用时机:在组件接收到新的
render()- 调用时机:在组件更新时调用。
- 作用:返回组件的 JSX 结构,描述组件应该如何重新渲染。
getSnapshotBeforeUpdate(prevProps, prevState)- 调用时机:在组件即将重新渲染之前调用。
- 作用:可以在这里捕获 DOM 更新前的状态(如滚动位置),并将返回值传递给
componentDidUpdate。 - 注意:通常与
componentDidUpdate配合使用。
componentDidUpdate(prevProps, prevState, snapshot)- 调用时机:在组件重新渲染之后调用。
- 作用:可以在这里执行 DOM 操作、发起网络请求或更新状态等。
- 注意:可以在这里比较
prevProps和prevState,以确定是否需要执行某些操作。
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→ 使用componentDidMount或constructor替代。componentWillReceiveProps→ 使用static getDerivedStateFromProps替代。componentWillUpdate→ 使用getSnapshotBeforeUpdate或componentDidUpdate替代。
6. 新生命周期钩子的执行顺序
以下是新生命周期钩子的典型执行顺序:
挂载阶段:
constructorstatic getDerivedStateFromPropsrendercomponentDidMount
更新阶段:
static getDerivedStateFromPropsshouldComponentUpdaterendergetSnapshotBeforeUpdatecomponentDidUpdate
卸载阶段:
componentWillUnmount
错误处理:
static getDerivedStateFromErrorcomponentDidCatch
7. 总结
React 新生命周期钩子更加清晰和安全,废弃了一些容易导致问题的旧钩子,并引入了 static getDerivedStateFromProps 和 getSnapshotBeforeUpdate 等新钩子。对于新项目,建议使用新的生命周期钩子,或者直接使用 React Hooks(如 useEffect)来管理组件的生命周期,因为它们提供了更简洁和灵活的方式来处理副作用和状态管理。