React 类组件的生命周期有哪些?对应 Hooks 怎么写?

类组件生命周期

挂载阶段:
  constructor → getDerivedStateFromProps → render → componentDidMount

更新阶段:
  getDerivedStateFromProps → shouldComponentUpdate → render → getSnapshotBeforeUpdate → componentDidUpdate

卸载阶段:
  componentWillUnmount

生命周期详解

class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    // 初始化 state、绑定方法
  }

  static getDerivedStateFromProps(props, state) {
    // 从 props 派生 state
    return null
  }

  shouldComponentUpdate(nextProps, nextState) {
    // 返回 false 阻止重渲染
    return true
  }

  componentDidMount() {
    // 挂载后:数据请求、订阅、DOM 操作
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // DOM 更新前读取信息(如滚动位置)
    return null
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // 更新后:DOM 操作、网络请求
  }

  componentWillUnmount() {
    // 卸载前:清除定时器、取消订阅
  }

  render() {
    return <div />
  }
}

Hooks 对应关系

类组件生命周期 Hooks 等价
constructor useState / useMemo 初始化
componentDidMount useEffect(() => {}, [])
componentDidUpdate useEffect(() => {}, [dep])
componentWillUnmount useEffect(() => { return cleanup }, [])
shouldComponentUpdate React.memo
getDerivedStateFromProps 渲染期间直接计算
getSnapshotBeforeUpdate useLayoutEffect
forceUpdate useReducer(强制触发)

代码对照

// 类组件
class User extends React.Component {
  componentDidMount() {
    fetchUser(this.props.id)
  }
  componentDidUpdate(prevProps) {
    if (prevProps.id !== this.props.id) {
      fetchUser(this.props.id)
    }
  }
  componentWillUnmount() {
    this.controller.abort()
  }
  render() { return <div>{this.state.user}</div> }
}

// Hooks 等价
function User({ id }) {
  const [user, setUser] = useState(null)

  useEffect(() => {
    const controller = new AbortController()
    fetchUser(id, { signal: controller.signal })
      .then(setUser)
    return () => controller.abort() // cleanup = componentWillUnmount
  }, [id]) // 依赖变化 = componentDidUpdate

  return <div>{user}</div>
}

废弃的生命周期(React 17+)

被废弃的原因是这些生命周期在 Fiber 异步渲染模式下可能被多次调用,导致不安全。

同分类其他题目