Zustand:React 状态管理的轻量级利器

346 阅读3分钟

一、引言

在现代 React 开发中,随着应用规模的扩大,组件之间共享状态的需求日益增加。React 本身提供了 useStateuseReducer 这样的本地状态管理工具,但在中大型项目中,这些工具往往难以满足跨组件、跨层级的状态共享需求。

传统的状态管理方案如 Redux 虽然功能强大,但其学习成本高、代码冗余多,常常让人望而却步。而 Zustand 的出现,为开发者提供了一种轻量、简洁、高效且易于上手的替代方案。

二、Zustand 是什么?

Zustand 是一个基于 React 的高性能状态管理库,它通过 一个 Hook 的方式 来创建和使用全局状态。它无需 Provider、无需 reducer、无需 action type,开箱即用,非常适合现代 React 项目的状态管理需求。

 核心特点:

  • 轻量级:压缩后体积极小(<1KB)。
  • Hooks 风格:完全基于 React Hooks,学习成本低。
  • 无嵌套结构:不需要 Provider 包裹组件。
  • 响应式更新:只订阅需要的状态,更新高效。
  • 支持中间件:如 devtools、持久化等。
  • TypeScript 支持良好

三、Zustand 的基本使用

1. 安装

pnpm i zustand

2. 创建 Store

接着,你可以创建一个 store 来集中管理应用中的状态,create 函数来创建一个全局状态仓库(store)。比如,我们可以创建一个计数器的状态管理模块:

// store/count.js
import { create } from 'zustand';

export const useCounterStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
}));

这里我们通过 create 函数定义了一个 store,它返回一个包含状态和修改状态方法的对象。你可以把它理解为一个全局可访问的“状态盒子”,任何组件都可以通过 useCounterStore 这个 Hook 来读取或修改这个状态。

3. 在组件中使用 Store

在组件中使用 Zustand 也非常简单。比如我们可以创建一个 Counter 组件:

// components/Counter.jsx
import { useCounterStore } from '../../store/count';

const Counter = () => {
  const { count, increment, decrement } = useCounterStore();

  return (
    <>
      <div>当前计数:{count}</div>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
    </>
  );
};

export default Counter;

可以看到,组件中并没有任何复杂的上下文传递或 dispatch 操作,只需要从 store 中“取出”状态和方法,就可以直接使用。这种写法不仅简洁,而且易于维护和测试。

4. 在父组件中展示全局状态

更进一步,我们可以在 App 根组件中展示这个全局状态:

// App.jsx
import { useCounterStore } from './store/count';

function App() {
  const { count } = useCounterStore();

  return (
    <>
      <h1>App 中的全局状态:{count}</h1>
      <Counter />
    </>
  );
}

export default App;

通过这种方式,我们可以轻松实现组件之间、层级之间状态的共享,而无需层层传递 props。这正是 Zustand 的核心价值之一:让状态真正“全局化”,并保持组件的纯粹 UI 职责。

四、Zustand 的优势对比

特性ZustandReduxContext + useReducer
使用方式Hook 风格,简洁直观复杂,需 reducer、action、dispatch简单但不适合复杂项目
学习成本
性能高效,只订阅需要的状态依赖 connect 或 useSelector 优化更新范围大,易触发多余渲染
开发体验高效、现代、支持 TypeScript传统、结构复杂简洁但缺乏扩展性
插件生态支持 devtools、persist 等插件插件丰富但配置繁琐
项目适用中小型项目首选,大型项目也可灵活使用大型项目首选小型项目或局部状态管理