Zustand 入门:React Native 状态管理的正确用法

一、Zustand 是什么,适合什么场景

Zustand 是一个轻量级、基于 hooks 的状态管理库,核心特点是:

  • 无 Provider(无需 Context 包裹)
  • API 极简(create + hooks)
  • 按需订阅(避免无关组件重渲染)
  • 对 React Native 友好(无额外平台依赖)
  • 可渐进式引入

非常适合以下 RN 场景:

  • 中小规模应用
  • RN Hybrid / Module 化工程
  • UI 状态 + 业务状态混合管理
  • 替代部分 Redux 的场景

二、安装

bash 复制代码
yarn add zustand
# 或
npm install zustand

React Native 无需额外配置。


三、最基础用法(核心必会)

1. 创建 Store

ts 复制代码
// store/useCounterStore.ts
import { create } from 'zustand';

type CounterState = {
  count: number;
  inc: () => void;
  dec: () => void;
};

export const useCounterStore = create<CounterState>((set) => ({
  count: 0,
  inc: () => set((state) => ({ count: state.count + 1 })),
  dec: () => set((state) => ({ count: state.count - 1 })),
}));

2. 在组件中使用

tsx 复制代码
import React from 'react';
import { View, Text, Button } from 'react-native';
import { useCounterStore } from './store/useCounterStore';

export default function Counter() {
  const count = useCounterStore((state) => state.count);
  const inc = useCounterStore((state) => state.inc);

  return (
    <View>
      <Text>Count: {count}</Text>
      <Button title="+" onPress={inc} />
    </View>
  );
}

关键点

  • selector 模式useStore(state => state.xxx)
  • 只订阅使用到的字段,避免全量刷新

四、推荐的工程化写法(重要)

❌ 不推荐

ts 复制代码
const store = useStore();

这样会导致任意状态变更都触发重渲染


✅ 推荐:拆分 selector

ts 复制代码
const count = useCounterStore((s) => s.count);
const inc = useCounterStore((s) => s.inc);

或:

ts 复制代码
const { count, inc } = useCounterStore(
  (s) => ({ count: s.count, inc: s.inc })
);

五、Zustand 在 React Native 中的常见模式

1. 全局 UI 状态(Loading / Modal)

ts 复制代码
type UIState = {
  loading: boolean;
  showLoading: () => void;
  hideLoading: () => void;
};

export const useUIStore = create<UIState>((set) => ({
  loading: false,
  showLoading: () => set({ loading: true }),
  hideLoading: () => set({ loading: false }),
}));
tsx 复制代码
const loading = useUIStore((s) => s.loading);

2. 业务状态(登录信息)

ts 复制代码
type User = {
  id: string;
  name: string;
};

type AuthState = {
  user?: User;
  login: (u: User) => void;
  logout: () => void;
};

export const useAuthStore = create<AuthState>((set) => ({
  user: undefined,
  login: (user) => set({ user }),
  logout: () => set({ user: undefined }),
}));

3. 异步 Action(非常自然)

ts 复制代码
type ListState = {
  list: string[];
  loading: boolean;
  fetchList: () => Promise<void>;
};

export const useListStore = create<ListState>((set) => ({
  list: [],
  loading: false,
  fetchList: async () => {
    set({ loading: true });
    const res = await fetch('https://example.com/list');
    const data = await res.json();
    set({ list: data, loading: false });
  },
}));

RN 中无需 thunk / saga。


六、性能优化(RN 场景非常关键)

1. 使用 shallow 避免对象对比

ts 复制代码
import { shallow } from 'zustand/shallow';

const { count, inc } = useCounterStore(
  (s) => ({ count: s.count, inc: s.inc }),
  shallow
);

2. 将高频 UI 状态拆分 Store

text 复制代码
store/
 ├── useAuthStore.ts
 ├── useUIStore.ts
 ├── useListStore.ts

避免一个大 Store。


七、持久化(AsyncStorage)

RN 常用:zustand + persist

ts 复制代码
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';

export const useAuthStore = create(
  persist(
    (set) => ({
      token: '',
      setToken: (token: string) => set({ token }),
      clearToken: () => set({ token: '' }),
    }),
    {
      name: 'auth-storage',
      storage: {
        getItem: AsyncStorage.getItem,
        setItem: AsyncStorage.setItem,
        removeItem: AsyncStorage.removeItem,
      },
    }
  )
);

八、Zustand vs Redux Toolkit(RN 实战视角)

维度 Zustand Redux Toolkit
学习成本 极低
样板代码 极少
Provider 不需要 必须
异步 原生支持 thunk / saga
DevTools
大型团队 一般 更适合

个人建议

  • RN 业务页面、模块级状态:Zustand
  • 复杂全局状态、多人协作:RTK
  • 二者可以共存

九、常见坑位总结

  1. 不要整 store 订阅
  2. 不要把所有状态塞进一个 store
  3. RN 中慎用大对象(列表分页要拆分)
  4. persist + AsyncStorage 要注意冷启动恢复时机
相关推荐
jin1233221 小时前
基于React Native鸿蒙跨平台地址管理是许多电商、外卖、物流等应用的重要功能模块,实现了地址的添加、编辑、删除和设置默认等功能
javascript·react native·react.js·ecmascript·harmonyos
2501_920931702 小时前
React Native鸿蒙跨平台医疗健康类的血压记录,包括收缩压、舒张压、心率、日期、时间、备注和状态
javascript·react native·react.js·ecmascript·harmonyos
2501_920931703 小时前
React Native鸿蒙跨平台使用useState管理健康记录和过滤状态,支持多种健康数据类型(血压、体重等)并实现按类型过滤功能
javascript·react native·react.js·ecmascript·harmonyos
2501_921930833 小时前
高级进阶 React Native 鸿蒙跨平台开发:InteractionManager 交互优化
react native·harmonyos
摘星编程5 小时前
OpenHarmony + RN:Stack堆栈导航转场
react native·react.js·harmonyos
摘星编程5 小时前
OpenHarmony环境下React Native:Tooltip自动定位
javascript·react native·react.js
2501_921930838 小时前
React Native 鸿蒙跨平台开发:LinearGradient 径向渐变
react native·react.js·harmonyos
2601_949593658 小时前
React Native 鸿蒙跨平台开发:LinearGradient 实战案例集
react native·react.js·harmonyos
2501_920931709 小时前
React Native鸿蒙跨平台跨平台阅读应用实现方案,包含书籍展示、分类筛选、搜索排序等功能模块,通过清晰的状态管理实现数据筛选与排序
react native·react.js·ecmascript·harmonyos
xiaoqi9229 小时前
React Native鸿蒙跨平台实现图片画廊类页面是视觉展示型APP(如摄影类、图库类、设计类APP)的核心载体,其核心需求是实现图片的流畅渲染
javascript·react native·react.js·ecmascript·harmonyos