挂载(Mounting)、更新(Updating)和卸载(Unmounting)的过程。
React 17 之前:
挂载阶段(Mounting):
-
constructor()
: 构造函数,在组件被创建时调用,用于初始化state、可以接收一个父组件传来的props、绑定事件处理方法。 -
componentWillMount(已弃用)
: 组件将要挂载 -
render()
: 在这里面我们会写一些html标签及自定义的函数,render执行完后便会将这些语句对应渲染到浏览器上面。 -
componentDidMount()
: 组件挂载后调用,通常用于进行异步数据获取、订阅事件等操作。
更新阶段(Updating):
-
componentWillReceiveProps(已弃用)
: 在组件接收到新的 props 之前调用。 -
shouldComponentUpdate()
: 决定是否重新渲染组件,在接收新props或state时调用,用于性能优化。 当更新state值的时候会执行这个函数,比如this.setState({})。 -
componentWillUpdate(已弃用)
: 会在组件接收到新的 props 或 state 并即将重新渲染之前被调用。 -
render()
: 和初始化时候执行的那个render一样,只是这里是更新值的,所以dom节点会重新更新一下。 -
componentDidUpdate()
: 组件更新后调用,通常用于处理DOM操作、网络请求等。
卸载阶段(Unmounting):
-
componentWillUnmount()
: 组件卸载前调用,用于清理定时器、取消订阅等操作。
React 17 之后:
挂载阶段(Mounting):
constructor()
-
static getDerivedStateFromProps
: React 会在初始挂载和后续更新时调用 render 之前调用它。它应该返回一个对象来更新 state,或者返回 null 就不更新任何内容。挂载阶段只调用一次,用于初始化 state。 render()
componentDidMount()
更新阶段(Updating):
-
static getDerivedStateFromProps
: 更新阶段每次组件接收到新的 props 时都会被调用。 shouldComponentUpdate()
render()
-
getSnapshotBeforeUpdate
: 会在 React 更新 DOM 之前时直接调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息(例如滚动的位置)。此生命周期方法返回的任何值都将作为参数传递给 componentDidUpdate。 componentDidUpdate()
卸载阶段(Unmounting):
componentWillUnmount()
除了上述生命周期方法,还有componentDidCatch()
用于捕获组件树中的错误。此外,React Hooks也提供了函数式组件中的生命周期替代方案,如useEffect()
用于处理副作用。
- componentDidCatch:
import React, { Component } from 'react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
this.setState({ hasError: true });
console.error('Error caught by ErrorBoundary:', error, info);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;
- useEffect: 在函数式组件中,可以使用React Hooks来替代类组件中的生命周期方法。
import { useState, useEffect } from 'react';
const FunctionalComponent = () => {
const [count, setCount] = useState(0);
// 相当于 componentDidMount 和 componentDidUpdate
useEffect(() => {
console.log('Component is mounted or updated');
// 清理函数,相当于 componentWillUnmount
return () => {
console.log('Component is about to unmount');
};
}, [count]); // 仅在count发生变化时触发
// 模拟 shouldComponentUpdate
const shouldUpdate = (nextProps, nextState) => {
if (nextState.count !== count) {
return true;
}
return false;
};
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increment Count</button>
</div>
);
};
export default FunctionalComponent;
常用的生命周期方法:
Class 组件中常用:
-
constructor()
: 用于初始化 state 和绑定方法。 -
render()
: 必须的方法,用于渲染组件。 -
componentDidMount()
: 在组件挂载后被调用,常用于进行 API 调用、订阅等。 -
componentDidUpdate(prevProps, prevState)
: 在组件更新后被调用,可以用于比较 props 和 state 的变化。 -
componentWillUnmount()
: 在组件卸载前被调用,常用于清理资源,如取消订阅、清除定时器等。
Function 组件中使用(Hooks):
-
useEffect()
: 用于在函数组件中执行副作用操作,类似于 componentDidMount、componentDidUpdate 和 componentWillUnmount。 -
useLayoutEffect()
: 类似于 useEffect,但它会在所有的 DOM 变更之后同步调用 effect,适用于读取 DOM 布局并同步触发重渲染的情况。
不常用的生命周期方法:
Class 组件中不常用:
-
UNSAFE_componentWillMount()
: 虽然可用,但官方不推荐使用,其用途通常可以在 componentDidMount 中实现。 -
UNSAFE_componentWillReceiveProps(nextProps)
: 虽然可用,但官方不推荐使用,推荐使用 getDerivedStateFromProps 或在 componentDidUpdate 中处理新的 props。 -
UNSAFE_componentWillUpdate(nextProps, nextState)
: 虽然可用,但官方不推荐使用,其用途通常可以在 componentDidUpdate 中实现。
Class 组件中特有的:
-
getDerivedStateFromProps(props, state)
: 这是一个静态方法,用于根据 props 更新 state,在组件挂载和更新时都会被调用