React Class 组件的生命周期可分为 挂载(Mounting)、更新(Updating)、卸载(Unmounting) 三个阶段。以下是各阶段生命周期方法的执行顺序及核心作用:
一、挂载阶段(Mounting)
当组件实例被创建并插入 DOM 时触发,执行顺序如下:
1. constructor()
- 作用:初始化
state
、绑定方法(如事件处理函数)。 - 注意:必须调用
super(props)
,否则this.props
未定义。 - 示例:
constructor(props) { super(props); this.state = { count: 0 }; this.handleClick = this.handleClick.bind(this); }
2. static getDerivedStateFromProps(nextProps, prevState)
(React 16.3+)
- 作用:根据新的
props
更新state
。 - 注意:静态方法,无
this
访问权;返回null
或新的state
对象。 - 示例:
static getDerivedStateFromProps(props, state) { if (props.value !== state.prevValue) { return { prevValue: props.value, derivedValue: props.value * 2 }; } return null; }
3. render()
- 作用:生成虚拟 DOM(必须返回
ReactElement
、数组、null
等)。 - 注意:纯函数,不应在此处修改
state
或执行副作用操作。 - 示例:
render() { return <div>{this.state.count}</div>; }
4. componentDidMount()
- 作用:组件挂载到 DOM 后执行副作用(如数据请求、订阅事件、操作 DOM)。
- 示例:
componentDidMount() { fetchData().then(data => this.setState({ data })); this.timer = setInterval(() => this.tick(), 1000); }
二、更新阶段(Updating)
当组件的 props
或 state
变化时触发,执行顺序如下:
1. static getDerivedStateFromProps(nextProps, prevState)
- 与挂载阶段相同,用于响应
props
变化更新state
。
2. shouldComponentUpdate(nextProps, nextState)
- 作用:决定是否重新渲染组件(返回
true
或false
)。 - 注意:性能优化关键点,避免不必要的渲染。
- 示例:
shouldComponentUpdate(nextProps, nextState) { return nextProps.id !== this.props.id || nextState.count !== this.state.count; }
3. render()
- 生成新的虚拟 DOM,与旧 DOM 对比后更新实际 DOM。
4. getSnapshotBeforeUpdate(prevProps, prevState)
(React 16.3+)
- 作用:在 DOM 更新前捕获信息(如滚动位置),返回值传递给
componentDidUpdate
。 - 示例:
getSnapshotBeforeUpdate() { return this.listRef.scrollHeight; }
5. componentDidUpdate(prevProps, prevState, snapshot)
- 作用:DOM 更新后执行副作用(如基于新 DOM 的操作)。
- 注意:避免直接调用
setState
,否则可能导致无限循环。 - 示例:
componentDidUpdate(prevProps, prevState, snapshot) { if (this.props.userID !== prevProps.userID) { this.fetchData(this.props.userID); } this.listRef.scrollTop = this.listRef.scrollHeight - snapshot; }
三、卸载阶段(Unmounting)
当组件从 DOM 中移除时触发:
1. componentWillUnmount()
- 作用:清理副作用(如取消网络请求、清除定时器、移除事件监听)。
- 示例:
componentWillUnmount() { clearInterval(this.timer); window.removeEventListener('resize', this.handleResize); }
四、错误处理(Error Handling)
当子组件抛出错误时触发:
1. static getDerivedStateFromError(error)
(React 16+)
- 作用:捕获子组件错误并更新
state
以显示错误 UI。 - 示例:
static getDerivedStateFromError(error) { return { hasError: true }; }
2. componentDidCatch(error, info)
(React 16+)
- 作用:记录错误信息(如上报到监控系统)。
- 示例:
componentDidCatch(error, info) { logErrorToService(error, info.componentStack); }
五、已废弃的生命周期方法(避免使用)
componentWillMount()
:已被constructor
和componentDidMount
替代。componentWillReceiveProps(nextProps)
:使用getDerivedStateFromProps
替代。componentWillUpdate(nextProps, nextState)
:使用getSnapshotBeforeUpdate
替代。
六、执行顺序流程图
挂载阶段:
constructor → getDerivedStateFromProps → render → componentDidMount
更新阶段:
getDerivedStateFromProps → shouldComponentUpdate → render → getSnapshotBeforeUpdate → componentDidUpdate
卸载阶段:
componentWillUnmount
错误处理:
子组件错误 → getDerivedStateFromError → render → componentDidCatch
七、总结
生命周期方法 | 阶段 | 核心用途 |
---|---|---|
constructor | 挂载 | 初始化状态和方法绑定 |
getDerivedStateFromProps | 挂载/更新 | 根据 props 更新 state |
render | 挂载/更新 | 生成虚拟 DOM |
componentDidMount | 挂载 | 副作用操作(数据请求、订阅) |
shouldComponentUpdate | 更新 | 决定是否重新渲染(性能优化) |
getSnapshotBeforeUpdate | 更新 | 捕获 DOM 更新前的信息 |
componentDidUpdate | 更新 | 更新后副作用操作 |
componentWillUnmount | 卸载 | 清理副作用(定时器、事件监听) |
通过合理利用生命周期方法,可以精准控制组件的渲染逻辑和副作用管理。