状态为什么要集中管理
组件一多,状态就散落在各处:这个组件自己存一份登录态、那个组件又存一份购物车,跨组件传靠层层 props,改一处牵全身。状态管理库把共享状态抽到一个全局 store 里,所有组件从同一份数据源读写,单向数据流让"状态怎么变"一目了然,调试也容易。
本文核心知识点
- store全局唯一状态容器。
- 单向流数据单向流动、可追溯。
- Redux纯函数 reducer 的经典模型。
- Pinia更轻、支持组合式的现代方案。
单向数据流:数据怎么流动
单向数据流是核心约定:组件触发动作(action)→ 动作被 reducer 处理、算出新状态 → store 更新 → 依赖它的组件自动重新渲染。数据只朝一个方向走,没有组件直接改全局状态,任何一次状态变化都有迹可循。
Redux 的核心模型
Redux 三个原则:单一 store、状态只读、用纯函数(reducer)描述变化。派发一个 action 对象,reducer 接收旧状态和 action、返回新状态。纯函数让状态变化可预测、可回放,时间旅行调试是它的招牌。代价是样板代码偏多。
function counter(state = 0, action) {
switch (action.type) {
case 'add': return state + 1;
default: return state;
}
}
Pinia:更轻的现代选择
Pinia 是 Vue 官方推荐、也被 React 项目广泛采用的现代 store:去掉了 action 类型字符串、mutations 合并进 actions,直接用组合式 API 定义 state、getters、actions,样板少、类型推断好。中小项目用 Pinia 往往比 Redux 更顺手。
const useCart = defineStore('cart', () => {
const list = ref([]);
const add = (item) => list.value.push(item);
return { list, add };
});
异步与副作用处理
reducer 必须是纯函数,异步请求、定时器这类副作用不能直接写进 reducer。Redux 用 thunk、saga 处理;Pinia 在 action 里直接写 async 函数即可。原则是:副作用在 action 层发起,拿到结果后再去提交纯状态更新。
状态该放哪、不该放哪
不是所有状态都该进全局 store:只被单个组件用的局部状态(输入框值、开关)留在组件里;跨多个组件共享、需要持久化或可追溯的(登录态、购物车、主题)才进 store。什么都塞进全局反而让结构变乱。
落地清单
- 共享状态集中进 store,局部状态留组件。
- 遵守单向数据流,不直接改全局状态。
- reducer 保持纯,副作用放 action 层。
- 中小项目优先 Pinia,大型团队选 Redux。
- 能用组件状态解决的,别上全局 store。