四、React 组件生命周期(类组件)
在 React 的类组件中,生命周期方法(Lifecycle Methods)用于在 组件挂载(Mount)、更新(Update)、卸载(Unmount) 时执行不同的操作。
(一)生命周期的三个阶段
1. 挂载阶段(Mount)
当组件被创建并插入 DOM 时,会依次调用以下方法:
生命周期方法 | 作用 |
---|---|
constructor | 初始化 state,绑定事件 |
static getDerivedStateFromProps | 根据 props 更新 state |
render | 渲染 UI |
componentDidMount | 组件挂载完成,可用于请求数据、DOM 操作 |
示例:
class Example extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
console.log("constructor");
}
componentDidMount() {
console.log("componentDidMount: 组件挂载完成");
}
render() {
console.log("render");
return <h1>Count: {this.state.count}</h1>;
}
}
2. 更新阶段(Update)
当 props
或 state
发生变化时,组件会进入更新阶段,调用以下方法:
生命周期方法 | 作用 |
---|---|
static getDerivedStateFromProps | 监听 props 变化更新 state |
shouldComponentUpdate | 控制组件是否需要重新渲染 |
render | 重新渲染组件 |
getSnapshotBeforeUpdate | 访问更新前的 DOM 数据 |
componentDidUpdate | 组件更新后执行(如请求新数据) |
示例:
class Example extends React.Component {
state = { count: 0 };
shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate");
return nextState.count % 2 === 0; // 只在 count 为偶数时更新
}
componentDidUpdate(prevProps, prevState) {
console.log("componentDidUpdate: 组件更新完成");
}
render() {
return <h1>Count: {this.state.count}</h1>;
}
}
3. 卸载阶段(Unmount)
当组件被移除时,会调用以下方法:
生命周期方法 | 作用 |
---|---|
componentWillUnmount | 组件即将被卸载,清理副作用(如取消定时器、移除事件监听等) |
示例:
class Example extends React.Component {
componentWillUnmount() {
console.log("componentWillUnmount: 组件即将被销毁");
}
render() {
return <h1>组件即将销毁</h1>;
}
}
(二)生命周期方法总结
阶段 | 生命周期方法 | 作用 |
---|---|---|
挂载 | constructor | 初始化 state 和绑定事件 |
getDerivedStateFromProps | 根据 props 变化更新 state | |
render | 渲染 UI | |
componentDidMount | 组件挂载完成,可执行副作用 | |
更新 | getDerivedStateFromProps | 监听 props 变化 |
shouldComponentUpdate | 控制是否重新渲染 | |
render | 重新渲染组件 | |
getSnapshotBeforeUpdate | 访问更新前的 DOM 数据 | |
componentDidUpdate | 组件更新完成后执行副作用 | |
卸载 | componentWillUnmount | 清理副作用(如移除监听器) |
五、React Hooks(函数组件)
React 16.8 之后,引入了 Hooks,让函数组件也能管理状态和生命周期,避免类组件的复杂性。
(一)常用 Hooks
Hook | 作用 |
---|---|
useState | 组件的状态管理 |
useEffect | 副作用(如请求数据、订阅事件) |
useContext | 共享全局状态 |
useReducer | 复杂状态管理(类似 Redux) |
useRef | 获取 DOM 元素或存储可变数据 |
useMemo | 计算缓存,优化性能 |
useCallback | 记忆化函数,防止不必要的重渲染 |
(二)useState
—— 状态管理
1. 定义状态
const [count, setCount] = useState(0);
2. 更新状态
setCount(count + 1);
3. 完整示例
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>增加</button>
</div>
);
}
(三)useEffect
—— 副作用管理
1. 基本用法
useEffect(() => {
console.log("组件渲染/更新时执行");
});
2. 依赖项控制
useEffect(() => {
console.log("count 变化时触发");
}, [count]); // 仅当 count 变化时执行
3. 清理副作用
useEffect(() => {
const interval = setInterval(() => {
console.log("定时任务");
}, 1000);
return () => clearInterval(interval); // 组件卸载时清除定时器
}, []);
(四)useRef
—— 获取 DOM 节点
function InputFocus() {
const inputRef = useRef(null);
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={() => inputRef.current.focus()}>聚焦输入框</button>
</div>
);
}
(五)useMemo
vs useCallback
1. useMemo
(缓存计算结果)
const expensiveValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
2. useCallback
(缓存函数)
const handleClick = useCallback(() => {
console.log("Clicked");
}, []);
六、总结
1. 类组件 vs 函数组件
对比项 | 类组件 | 函数组件 |
---|---|---|
语法复杂度 | 复杂 | 简单 |
状态管理 | this.state | useState |
生命周期 | componentDidMount 等 | useEffect |
适用场景 | 旧项目 / 复杂逻辑 | 现代开发推荐 |
2. Hooks 的使用场景
Hook | 作用 |
---|---|
useState | 状态管理 |
useEffect | 副作用管理 |
useRef | 获取 DOM |
useMemo | 计算优化 |
useCallback | 记忆化函数 |