MST

星途 面试题库

面试题:React 新旧生命周期方法在组件更新阶段的性能影响

从性能优化的角度出发,分析在 React 组件更新阶段,旧生命周期的 shouldComponentUpdate、componentWillUpdate、componentDidUpdate 与新生命周期对应的 getDerivedStateFromProps、shouldComponentUpdate、getSnapshotBeforeUpdate、componentDidUpdate 方法的不同,以及如何选择合适的方法以提升性能。
31.4万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

旧生命周期与新生命周期方法差异

shouldComponentUpdate

  • 相同点:新旧生命周期中的 shouldComponentUpdate 功能类似,都是用于判断组件是否需要更新。通过返回 truefalse 来决定是否继续执行后续的更新流程,从而避免不必要的重新渲染,提升性能。
  • 不同点:新生命周期的 shouldComponentUpdate 接收 nextPropsnextState 作为参数,旧生命周期同样接收这两个参数,但在实际应用场景上,新生命周期下配合 React.memo(对于函数组件)等方式,在进行浅比较优化时更加直观和便捷。

componentWillUpdate 与 getDerivedStateFromProps

  • componentWillUpdate:在组件接收到新的 propsstate 即将更新时被调用。但此方法存在一些问题,在异步渲染模式下可能会被多次调用,导致一些不可预测的行为。例如在这个方法中直接修改 state 可能会引起副作用。
  • getDerivedStateFromProps:这是一个静态方法,它在每次渲染前都会被调用,包括初始挂载和后续更新。它接收 propsstate 作为参数,返回一个对象来更新 state,或者返回 null 表示不更新 state。它主要用于根据 props 来更新 state,这样可以避免在 componentWillUpdate 中可能出现的副作用问题,同时也更符合 React 单向数据流的理念。

getSnapshotBeforeUpdate 与 componentDidUpdate

  • getSnapshotBeforeUpdate:在最近一次渲染输出(提交到 DOM 节点)之前调用。它可以获取到即将被覆盖的 DOM 状态,返回值将作为 componentDidUpdate 的第三个参数 snapshot 传递。这个方法对于需要在更新前读取 DOM 状态并基于此进行一些操作的场景非常有用,例如获取滚动位置等。
  • componentDidUpdate:在组件更新后被调用。在旧生命周期中,它在组件更新完成后执行,可用于操作 DOM、发起网络请求等副作用操作。在新生命周期下,结合 getSnapshotBeforeUpdate,可以在获取到更新前 DOM 状态的基础上,在更新后进行相应处理。

选择合适方法提升性能

  • shouldComponentUpdate
    • 对于简单组件,手动实现 shouldComponentUpdate 进行浅比较,判断 propsstate 是否有变化,避免不必要更新。
    • 对于函数组件,可使用 React.memo,它默认对 props 进行浅比较,与 shouldComponentUpdate 类似功能,减少重复渲染。
  • getDerivedStateFromProps
    • state 的值在任何时候都取决于 props 时,使用 getDerivedStateFromProps 来更新 state。例如根据传入的 props 初始化或更新 state 的一些衍生数据。但要注意避免过度使用,因为频繁更新 state 也可能影响性能。
  • getSnapshotBeforeUpdatecomponentDidUpdate
    • 当需要在更新后基于更新前的 DOM 状态进行操作时,使用 getSnapshotBeforeUpdate 获取 DOM 状态,在 componentDidUpdate 中处理。如实现滚动条位置保持等功能。
    • componentDidUpdate 中进行副作用操作,如网络请求、DOM 操作等,但要注意避免在不必要的更新时执行这些操作,结合 shouldComponentUpdate 来判断是否需要执行这些副作用。