Zustand VS Redux
在文章开始前咱们先唠嗑一下,各位平时用哪个更多点呢?大数据不会骗人:
首先GitHub上的 Star 数量比较: 

其次每周的下载数量比较:


显然,想必用Zustand的可能大概也许应该会居多(单纯看数据来讲)。那么明明Redux才是大哥,为啥被Zustand这个小弟后来居上了?
给大家一个表:
| 对比项 | Redux(老牌流程派) | Zustand(新晋清爽党) |
|---|---|---|
| 上手门槛 | 高:得记 action type、reducer、Provider 等一堆概念 | 低:会用 React Hook 就能写,几行代码起手 |
| 代码量 | 多:改个 count 得写 action、reducer 一堆模板代码 | 少:创建 store + 组件调用,加起来不到 20 行 |
| 组件里怎么用 | 得用 useSelector 取数据 + useDispatch 发动作 |
直接 useStore( state => state.xxx ) 一步到位 |
| 要不要包 Provider | 必须包:得用 <Provider store={store}> 裹整个 App |
不用包:组件直接调用 store,省一层嵌套 |
| 适合场景 | 大型复杂项目(多人协作、状态逻辑多) | 中小型项目 / 快速开发(想少写代码、快速落地) |
相信看完表大家已经很明了了,那么如果还想深入了解的可以自行去搜搜,我们唠嗑就到这,开始今天的学习。
具体资料大家去官网看:
前言
想象一下:你正在开发一个 React 项目,Home 组件 要改个数字,About 组件 得同步显示,List 组件 还要从接口拉数据 ------ 要是每个组件都自己存状态,代码早乱成一锅粥了!今天咱们就用 Zustand 这个躺平神器 ,把这些组件串成丝滑的整体,顺便解锁 React 全局状态的 "极简玩法"。
一、先搭个 "状态仓库":Zustand 初体验
Zustand 是啥?你可以把它理解成一个 "共享储物柜" :组件们不用再互相传 props,直接从这个柜子里拿数据、调方法就行。
首先你需要下载Zustand(在开篇的资料里也可以找到~):

先看我们的第一个 "储物格"------count.js(负责管理计数状态):
js
// src/store/count.js
import { create } from "zustand";
// 用 create 造一个"状态仓库"
const useCountStore = create((set) => ({
// 存数据:初始计数是0,还有个默认年龄19
count: 0,
age: 19,
// 存方法:点一下计数+1(set会自动更新视图)
increase: () => set((state) => ({ count: state.count + 1 })),
// 传个参数,计数直接减val
decrease: (val) => set((state) => ({ count: state.count - val }))
}))
export default useCountStore;
就这么几行,一个能 "存数据 + 改数据" 的全局状态就搞定了 ------ 比 Redux 轻量到没朋友!
二、组件 "抢着用":状态共享原来这么丝滑
有了仓库,组件们就能 "按需取货" 了。先看 Home 组件(负责操作计数):
jsx
// src/components/Home.jsx
import useCountStore from '../store/count.js'
export default function Home() {
// 从仓库里"拿"count数据
let count = useCountStore((state) => state.count);
// 从仓库里"拿"increase、decrease方法
const increase = useCountStore((state) => state.increase);
const decrease = useCountStore((state) => state.decrease);
return (
<div>
{/* 点按钮直接调仓库里的方法,不用传参! */}
<button onClick={increase}>发送-{count}</button>
<button onClick={() => decrease(10)}>减少-{count}</button>
</div>
)
}
再看 About 组件(负责显示计数):
jsx
// src/components/About.jsx
import useCountStore from "../store/count"
export default function About() {
// 同样从仓库拿count,Home改了这里自动更!
let count = useCountStore((state) => state.count);
return (
<div>
<h2>title-{count}</h2>
</div>
)
}
点击前:

点击10次发送后:

刷新然后点击10次减少后:

你看你看你看看看,Home 点按钮改了 count,About 里的标题直接同步更新 ------ 连 props 都不用传,这丝滑感谁用谁知道!
三、进阶玩法:状态里塞接口请求
光存数字才哪到哪,还不够炫 !咱们给仓库加个 "拉接口" 的功能。先写 list.js(负责管理列表数据):
js
// src/store/list.js
import { create } from "zustand";
// 先写个请求接口的函数
const fetchApi = async () => {
const response = await fetch('https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer');
const res = await response.json();
return res.data; // async函数的return会变成Promise的resolve值
}
// 造个存列表的仓库
const useListStore = create((set) => ({
list: [], // 初始列表是空数组
// 存个"拉列表"的方法,里面调用接口
fetchList: async () => {
const res = await fetchApi();
set({ list: res }) // 拿到数据后更新list
}
}))
export default useListStore;
然后让 List 组件 用这个仓库:
jsx
// src/components/List.jsx
import { useEffect } from "react";
import useListStore from "../store/list"
export default function List() {
// 从仓库拿list数据和fetchList方法
const list = useListStore((state) => state.list);
const fetchList = useListStore((state) => state.fetchList);
// 组件一加载就调用接口拉数据
useEffect(() => {
fetchList()
}, [])
return (
<div>
{/* 拿到数据直接map渲染 */}
{list.map((item) => {
return <div key={item.name}>{item.name}</div>
})}
</div>
)
}
接口数据就出现在浏览器上啦:

打开页面,List 组件 会自动拉接口、存数据、渲染列表 ------ 状态管理 + 接口请求,一套流程直接在仓库里包圆了!
四、最后一步:把组件都塞进 App
最后在 App.jsx 里把这些组件拼起来:
jsx
import Home from "./components/Home"
import About from "./components/About"
import List from "./components/List"
export default function App() {
return (
<div>
<Home></Home>
<About></About>
<List></List>
</div>
)
}

启动项目,你会看到:About 显示着计数,List 自动渲染接口数据 ------ 这就是 Zustand 给 React 带来的 "状态自由"!
总结
Zustand 堪称 React 状态管理的 "轻骑兵" :无需写冗余的 reducer、不用嵌套 Provider 包裹组件树,几行代码就能搭建全局状态仓库。它剥离了传统状态管理的繁琐仪式感,让我们彻底摆脱模板代码的束缚,聚焦业务本身。
结语
相比 Redux 的 "厚重" 和 Context API 在高频更新下的性能短板,Zustand 就像一把恰到好处的 "瑞士军刀",轻巧却锋利,用最简单的方式解决了 React 组件间的状态共享难题,让开发者能把更多精力放在业务逻辑本身,而不是状态管理的 "套路" 里。
好的工具从来不是炫技的枷锁,而是让开发者回归创造本身的桥梁。