前端状态管理:什么时候该上 Store,什么时候别乱用
一、先搞懂:什么是"状态"
前端说的"状态(state)",就是会变化、且影响页面展示的数据:
- 用户是否登录、当前用户名、头像;
- 购物车里的商品列表;
- 一个列表的翻页、筛选条件;
- 甚至"弹窗现在开没开"这种 UI 状态。
这些数据的特点是:会变,而且可能多个地方都要用。组件自己的局部变量扛得住小的,扛不住"跨组件共享"。
二、为什么需要状态管理
先看"不上状态管理"会怎样。下面左图是常见的痛点——props 层层透传(prop drilling):

数据在组件 A 手里,但最底下的组件 C 才要用。中间所有组件都得"二传"一遍 props:A 传给 B,B 再传给 C。结果就是:
- 中间组件被迫携带它根本不关心的数据;
- 改一个字段,一整条链路都得跟着动;
- 兄弟组件之间想共享数据,更是没地方放。
状态管理的解法很直白:把共享数据抽到一个"中央仓库(Store)"里,谁要用谁直接连,不通过中间人。右边那张图就是这个意思——X、Y、Z 各自直连 Store,互不依赖。
三、主流方案有哪些
不同框架生态不一样,但思想一致:
| 框架 | 官方/主流方案 | 特点 |
|---|---|---|
| Vue 2 | Vuex | 老牌,概念多(state/mutation/action/getter) |
| Vue 3 | Pinia | Vue 官方推荐,API 极简,TS 友好 |
| React | Redux / Zustand / Context | Redux 规范但样板代码多;Zustand 轻量好用;Context 适合小范围 |
以 Pinia 为例,定义一个 store 就几行:
// stores/user.ts
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
name: '',
isLogin: false,
}),
actions: {
login(name: string) {
this.name = name
this.isLogin = true
},
logout() {
this.name = ''
this.isLogin = false
},
},
})
组件里直接用,任何地方拿到都是同一份:
<script setup>
import { useUserStore } from '@/stores/user'
const user = useUserStore()
</script>
<template>
<button @click="user.login('张三')">登录</button>
<p v-if="user.isLogin">欢迎,{{ user.name }}</p>
</template>
四、核心思想:单向数据流
不管是 Pinia 还是 Redux,都遵循单向数据流——数据只沿一个方向走,不能"任意组件私自修改全局状态":

回路是:
- View 读 state 渲染:页面根据 Store 里的状态画出来。
- 用户操作派发 action:点按钮等交互,触发一个 action。
- action 修改 state:只有 action/mutation 能动 state,且逻辑集中。
- state 变了,View 响应式更新:回到第 1 步。
好处是可预测、可追踪:状态为什么变、被谁变,都有明确路径,调试时一眼能看出来,不会"不知道谁改了我的数据"。
五、什么时候其实不需要它
状态管理被很多人当银弹,见项目就上,结果杀鸡用牛刀。下面情况先别急着用:
- 纯展示页:数据只在单个组件内用,父子传一下就行。
- 小项目 / Demo:两三个组件,上 Store 反而增加复杂度。
- 一次性数据:请求完用完就扔、不共享,放组件局部即可。
判断标准就一条:这份数据有没有被"多个互不相关的组件"共享? 有,才考虑 Store;没有,局部 state 足够。
六、新手常见误区
- 把什么都塞进 Store——连"这个按钮按下变个色"也全局存,store 变成垃圾场。局部 UI 状态留在组件里。
- 在组件里直接改 state——绕过 action 改,破坏单向流,后期难追踪。走 action。
- Store 里存敏感信息——token、密钥别放前端全局状态里裸奔,参照 JWT 的存储建议。
- 忽视持久化——登录态刷新页面没了?用
pinia-plugin-persistedstate这类插件把需要的部分存 localStorage/IndexedDB。
七、小结
状态管理并不是"高级功能",而是解决"跨组件共享数据"这一具体痛点的工具。它的价值在于:用中央 Store 消灭 props 透传,用单向数据流让状态变化可追踪。
但请记住反向那句话:不是所有数据都该进 Store。能局部解决的,就别全局化。先问"有没有多组件共享",再决定上不上。
- 点赞
- 收藏
- 关注作者
评论(0)