Zustand在ReactNative中的工程实践与性能优化总结
一、为什么在 React Native 中选择 Zustand 在 RN 工程中,引入状态管理通常会面临几个现实问题: 项目可能是 Hybrid 架构,RN 只是一个子模块 原生工程结构复杂,不希望引
Zustand 是一个轻量级、基于 hooks 的状态管理库,核心特点是:
非常适合以下 RN 场景:
yarn add zustand
# 或
npm install zustand
React Native 无需额外配置。
// 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 })),
}));
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>
);
}
useStore(state => state.xxx)
const store = useStore();
这样会导致任意状态变更都触发重渲染
const count = useCounterStore((s) => s.count);
const inc = useCounterStore((s) => s.inc);
或:
const { count, inc } = useCounterStore(
(s) => ({ count: s.count, inc: s.inc })
);
type UIState = {
loading: boolean;
showLoading: () => void;
hideLoading: () => void;
};
export const useUIStore = create<UIState>((set) => ({
loading: false,
showLoading: () => set({ loading: true }),
hideLoading: () => set({ loading: false }),
}));
const loading = useUIStore((s) => s.loading);
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 }),
}));
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。
import { shallow } from 'zustand/shallow';
const { count, inc } = useCounterStore(
(s) => ({ count: s.count, inc: s.inc }),
shallow
);
store/
├── useAuthStore.ts
├── useUIStore.ts
├── useListStore.ts
避免一个大 Store。
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 | Redux Toolkit |
|---|---|---|
| 学习成本 | 极低 | 中 |
| 样板代码 | 极少 | 多 |
| Provider | 不需要 | 必须 |
| 异步 | 原生支持 | thunk / saga |
| DevTools | 有 | 强 |
| 大型团队 | 一般 | 更适合 |
个人建议: