React 组件在其生命周期中有多个阶段,每个阶段都有特定的生命周期函数(Lifecycle Methods)。这些函数允许你在组件的不同阶段执行特定的操作。以下是 React 组件生命周期的主要阶段及其对应的生命周期函数,并结合了 React 16.3+ 的变化。
一、挂载阶段(Mounting)
在组件首次被挂载到 DOM 时会触发的一系列生命周期函数。
-  
constructor(props):- 初始化组件的状态和绑定事件处理器。
 - 注意:尽量避免在此进行复杂的计算或副作用操作。
 
constructor(props) {super(props);this.state = { count: 0 };this.handleClick = this.handleClick.bind(this); // 绑定事件处理器 } -  
static getDerivedStateFromProps(nextProps, prevState):- 在组件挂载和更新之前调用,用于根据新的 props 更新 state。
 - 返回一个对象来更新 state,或者返回 
null表示不需要更新。 
static getDerivedStateFromProps(nextProps, prevState) {if (nextProps.value !== prevState.value) {return { value: nextProps.value };}return null; } -  
render():- 必须实现的方法,用于渲染组件的虚拟 DOM。
 - 不应该在这里进行副作用操作(如 API 调用、DOM 操作等)。
 
render() {return <div>{this.state.count}</div>; } -  
componentDidMount():- 组件挂载完成后调用,通常用于发起网络请求、订阅事件等副作用操作。
 
componentDidMount() {fetch('/api/data').then(response => this.setState({ data: response.data })); } 
二、更新阶段(Updating)
当组件的 props 或 state 发生变化时,会触发一系列更新阶段的生命周期函数。
-  
static getDerivedStateFromProps(nextProps, prevState):- 同挂载阶段的 
getDerivedStateFromProps,用于根据新的 props 更新 state。 
 - 同挂载阶段的 
 -  
shouldComponentUpdate(nextProps, nextState):- 判断组件是否需要重新渲染。返回 
false可以阻止不必要的重新渲染,从而优化性能。 
shouldComponentUpdate(nextProps, nextState) {return nextState.count !== this.state.count; } - 判断组件是否需要重新渲染。返回 
 -  
render():- 同挂载阶段的 
render()方法,用于渲染组件的虚拟 DOM。 
 - 同挂载阶段的 
 -  
getSnapshotBeforeUpdate(prevProps, prevState):- 在最新的渲染输出提交给 DOM 之前调用,可以捕获一些 DOM 信息(如滚动位置),以便在 
componentDidUpdate中使用。 
getSnapshotBeforeUpdate(prevProps, prevState) {if (prevProps.items.length < this.props.items.length) {return this.listRef.scrollHeight;}return null; } - 在最新的渲染输出提交给 DOM 之前调用,可以捕获一些 DOM 信息(如滚动位置),以便在 
 -  
componentDidUpdate(prevProps, prevState, snapshot):- 组件更新完成后调用,可以在此进行副作用操作(如网络请求、DOM 操作等)。
 
componentDidUpdate(prevProps, prevState, snapshot) {if (snapshot !== null) {this.listRef.scrollTop = this.listRef.scrollHeight - snapshot;} } 
三、卸载阶段(Unmounting)
当组件从 DOM 中卸载时会触发的生命周期函数。
-  
componentWillUnmount():- 组件卸载和销毁之前立刻调用,通常用于清理工作,如取消网络请求、清除定时器、移除事件监听器等。
 
componentWillUnmount() {clearInterval(this.timerID);this.subscription.remove(); } 
四、错误处理阶段(Error Handling)
当组件抛出错误时会触发的生命周期函数。
-  
static getDerivedStateFromError(error):- 当子组件抛出错误时调用,用于更新 state 以便显示错误 UI。
 
static getDerivedStateFromError(error) {return { hasError: true }; } -  
componentDidCatch(error, info):- 当子组件抛出错误时调用,通常用于记录错误日志或上报错误。
 
componentDidCatch(error, info) {logErrorToService(error, info); } 
五、React 16.3+ 生命周期变化
随着 React 16.3+ 的发布,部分生命周期函数被废弃或新增了一些新的生命周期函数:
-  
废弃的生命周期:
componentWillMount(建议使用componentDidMount)componentWillReceiveProps(建议使用static getDerivedStateFromProps)componentWillUpdate(建议使用getSnapshotBeforeUpdate)
 -  
新增的生命周期:
getDerivedStateFromProps:用于在挂载和更新前根据 props 更新 state。getSnapshotBeforeUpdate:在最新的渲染输出提交给 DOM 之前调用,捕获一些 DOM 信息。
 
钩子函数(Hooks)
随着 React Hooks 的引入,许多类组件的生命周期方法可以通过钩子函数来实现:
-  
useEffect:- 相当于 
componentDidMount、componentDidUpdate和componentWillUnmount的组合。 
useEffect(() => {// 类似 componentDidMount 和 componentDidUpdatefetchData().then(data => setState({ data }));// 清理函数,类似 componentWillUnmountreturn () => {cleanup();}; }, [props.userID]); // 依赖项数组 - 相当于 
 -  
useLayoutEffect:- 类似 
useEffect,但在所有 DOM 变更之后同步调用,适用于需要同步执行的副作用操作。 
 - 类似 
 -  
useMemo和useCallback:- 用于性能优化,类似于 
shouldComponentUpdate。 
 - 用于性能优化,类似于 
 
总结
React 组件的生命周期分为三个主要阶段:挂载(Mounting)、更新(Updating)和卸载(Unmounting)。每个阶段都有相应的生命周期函数,帮助开发者在组件的不同生命周期中执行特定的操作。
- 挂载阶段:初始化状态、渲染组件、发起数据请求等。
 - 更新阶段:判断是否需要重新渲染、捕获 DOM 信息、执行副作用操作等。
 - 卸载阶段:清理资源、取消订阅等。
 
通过合理使用这些生命周期函数,可以构建出更加健壮和高效的 React 应用程序。同时,现代 React 开发中推荐使用 Hooks 来替代类组件的生命周期方法,以简化代码并提高可维护性。
理解这些生命周期函数及其作用,不仅有助于编写高效且易于维护的 React 组件,还能更好地应对复杂的应用场景。