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. 新生命周期钩子的执行顺序
以下是新生命周期钩子的典型执行顺序:
挂载阶段:
constructor
static getDerivedStateFromProps
render
componentDidMount
更新阶段:
static getDerivedStateFromProps
shouldComponentUpdate
render
getSnapshotBeforeUpdate
componentDidUpdate
卸载阶段:
componentWillUnmount
错误处理:
static getDerivedStateFromError
componentDidCatch
7. 总结
React 新生命周期钩子更加清晰和安全,废弃了一些容易导致问题的旧钩子,并引入了 static getDerivedStateFromProps
和 getSnapshotBeforeUpdate
等新钩子。对于新项目,建议使用新的生命周期钩子,或者直接使用 React Hooks(如 useEffect
)来管理组件的生命周期,因为它们提供了更简洁和灵活的方式来处理副作用和状态管理。