Skip to content

React 生命周期 ​

生命周期总览 ​

React 类组件的生命周期分为三个阶段:挂载 → 更新 → 卸载。

React Lifecycle

在线图表:https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

新版生命周期 ​

挂载阶段 ​

方法说明
constructor初始化 state、绑定事件
static getDerivedStateFromProps(props, state)根据 props 更新 state,返回对象或 null
render渲染 UI
componentDidMountDOM 已挂载,适合数据请求、DOM 操作
jsx
constructor(props) {
  super(props)
  this.state = { count: 0 }
}

static getDerivedStateFromProps(props, state) {
  // 返回对象合并 state,返回 null 不做任何操作
  if (props.count !== state.count) {
    return { count: props.count }
  }
  return null
}

componentDidMount() {
  // 请求数据、添加事件监听
  fetch('/api/data').then(res => this.setState({ data: res }))
}
constructor(props) {
  super(props)
  this.state = { count: 0 }
}

static getDerivedStateFromProps(props, state) {
  // 返回对象合并 state,返回 null 不做任何操作
  if (props.count !== state.count) {
    return { count: props.count }
  }
  return null
}

componentDidMount() {
  // 请求数据、添加事件监听
  fetch('/api/data').then(res => this.setState({ data: res }))
}

更新阶段 ​

方法说明
static getDerivedStateFromPropsprops 变化时更新 state
shouldComponentUpdate(nextProps, nextState)是否重新渲染,默认 true
render渲染 UI
getSnapshotBeforeUpdate(prevProps, prevState)获取更新前快照,返回值传给 componentDidUpdate
componentDidUpdate(prevProps, prevState, snapshot)更新完成
jsx
shouldComponentUpdate(nextProps, nextState) {
  // 返回 false 跳过渲染(性能优化)
  return nextState.count !== this.state.count
}

getSnapshotBeforeUpdate(prevProps, prevState) {
  // 获取滚动位置等快照
  return this.listRef.current.scrollHeight
}

componentDidUpdate(prevProps, prevState, snapshot) {
  if (snapshot !== null) {
    // 使用快照值恢复滚动位置
    this.listRef.current.scrollTop = this.listRef.current.scrollHeight - snapshot
  }
}
shouldComponentUpdate(nextProps, nextState) {
  // 返回 false 跳过渲染(性能优化)
  return nextState.count !== this.state.count
}

getSnapshotBeforeUpdate(prevProps, prevState) {
  // 获取滚动位置等快照
  return this.listRef.current.scrollHeight
}

componentDidUpdate(prevProps, prevState, snapshot) {
  if (snapshot !== null) {
    // 使用快照值恢复滚动位置
    this.listRef.current.scrollTop = this.listRef.current.scrollHeight - snapshot
  }
}

卸载阶段 ​

jsx
componentWillUnmount() {
  // 清理:定时器、事件监听、WebSocket 等
  clearInterval(this.timer)
  window.removeEventListener('resize', this.handleResize)
}
componentWillUnmount() {
  // 清理:定时器、事件监听、WebSocket 等
  clearInterval(this.timer)
  window.removeEventListener('resize', this.handleResize)
}

错误处理 ​

jsx
// 捕获渲染阶段错误,返回对象合并 state
static getDerivedStateFromError(error) {
  return { hasError: true }
}

// 捕获 commit 阶段错误
componentDidCatch(error, info) {
  console.log('捕获错误:', error, info)
}
// 捕获渲染阶段错误,返回对象合并 state
static getDerivedStateFromError(error) {
  return { hasError: true }
}

// 捕获 commit 阶段错误
componentDidCatch(error, info) {
  console.log('捕获错误:', error, info)
}

区别:

  • getDerivedStateFromError — 在 render phase 调用,用于更新 UI
  • componentDidCatch — 在 commit phase 调用,用于副作用(如上报错误)

旧版生命周期 ​

React 16 之前使用,部分已废弃(加 UNSAFE_ 前缀):

挂载:
  constructor → componentWillMount → render → componentDidMount

更新(props 变化):
  componentWillReceiveProps → shouldComponentUpdate → componentWillUpdate → render → componentDidUpdate

更新(state 变化):
  shouldComponentUpdate → componentWillUpdate → render → componentDidUpdate

卸载:
  componentWillUnmount
挂载:
  constructor → componentWillMount → render → componentDidMount

更新(props 变化):
  componentWillReceiveProps → shouldComponentUpdate → componentWillUpdate → render → componentDidUpdate

更新(state 变化):
  shouldComponentUpdate → componentWillUpdate → render → componentDidUpdate

卸载:
  componentWillUnmount

已废弃的生命周期(避免使用):

废弃方法替代方案
componentWillMountconstructor 或 componentDidMount
componentWillReceivePropsgetDerivedStateFromProps
componentWillUpdategetSnapshotBeforeUpdate + componentDidUpdate

forceUpdate ​

跳过 shouldComponentUpdate 强制渲染:

jsx
this.forceUpdate(() => {
  console.log('强制更新完成')
})
this.forceUpdate(() => {
  console.log('强制更新完成')
})

生命周期图谱(旧版) ​

Old Lifecycle