一、State 的核心概念与特点
-
状态驱动 UI
State 是 React 组件内部存储动态数据的对象,用于控制组件的渲染逻辑。当 State 变化时,组件会重新渲染,实现 UI 与数据的同步。 -
核心特点
- 私有性:State 是组件独有的,父组件无法直接访问子组件的 State。
- 不可变性:直接修改
this.state无效,必须通过setState()方法更新。 - 异步更新:React 会将多次
setState()合并为单次更新以提高性能,需通过函数式更新确保数据正确性。 - 合并更新:
setState()会浅合并对象属性,而非替换整个 State。
二、State 的使用方法
1. 类组件中的 State
初始化方式
// ES6 构造函数初始化
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 }; // 构造函数内初始化
}
}
// ES7 属性初始化器(推荐)
class Counter extends React.Component {
state = { count: 0 }; // 类属性直接定义
}
更新方法
// 对象式更新(可能因异步合并导致问题)
this.setState({ count: this.state.count + 1 });
// 函数式更新(推荐)
this.setState((prevState) => ({
count: prevState.count + 1
})); // 基于最新状态避免竞态问题
2. 函数组件中的 State(Hooks)
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // 初始值可传函数延迟计算
const handleClick = () => {
setCount(prev => prev + 1); // 函数式更新确保并发安全
};
return <button onClick={handleClick}>{count}</button>;
}
三、State 与生命周期的交互
1. 类组件的生命周期
- 挂载阶段
constructor→render→componentDidMount(发起网络请求)。 - 更新阶段
shouldComponentUpdate(性能优化)→render→componentDidUpdate(DOM 操作)。 - 卸载阶段
componentWillUnmount(清理定时器/订阅)。
2. 异步更新与副作用处理
- 回调函数:
setState(updater, callback)可在更新后执行逻辑。 - 副作用时机:网络请求应放在
componentDidMount或useEffect中,避免阻塞渲染。
四、进阶场景与最佳实践
1. 复杂状态管理
-
嵌套对象更新
使用展开运算符进行深拷贝(需注意浅拷贝问题):this.setState(prev => ({ user: { ...prev.user, name: 'Alice' } })); -
状态提升
多个组件共享状态时,通过父组件传递 Props 实现。
2. 性能优化
- 避免冗余渲染
使用shouldComponentUpdate或React.memo跳过不必要的渲染。 - 批量更新
React 自动合并事件处理器中的setState(),异步代码(如setTimeout)需手动批处理。
3. 常见问题
- 直接修改 State
错误示例:this.state.count = 1→ 必须用setState()。 - 异步陷阱
console.log(this.state.count)可能输出旧值,需在回调中获取最新值。
五、函数组件与 Hooks 的扩展
1. useState 进阶用法
- 惰性初始化
const [data, setData] = useState(() => fetchInitialData()); - 自定义 Hook
封装状态逻辑复用(如useFormInput)。
2. 状态管理库集成
- Context API:跨组件层级传递状态。
- Redux/Zustand:复杂应用的状态集中管理(需结合中间件处理异步)。