Skip to content
返回构建教程

状态管理

选正确状态策略——服务端状态 vs 客户端状态——不过度工程化。

为什么

最常见 React 错误是把服务端数据放 useState/useReducer,意味着无缓存、无重取、无乐观更新、到处过期数据。服务端状态(API 数据)和客户端状态(UI 开关、表单输入)有完全不同生命周期应用不同工具。服务端状态属 TanStack Query(缓存、重取、失效);客户端状态属 useState 或跨组件共享用 Zustand。2026 年 Redux 几乎永不正确——它为 React Query 和服务端组件之前的世界设计。正确选择意味着更少代码、更少 bug、无'为何显示昨天数据?'工单。

何时使用

应用有 ≥3 数据获取组件时。搭 TanStack Query 约 1-2 小时。静态内容站可跳过。

如何做

1. 装 TanStack Query 并在 QueryClientProvider 包应用
   - const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 60_000 } } })
   - 放根布局,路由之上

2. 所有服务端状态(GET 请求)用 useQuery
   - const { data, isLoading, error } = useQuery({ queryKey: ["users"], queryFn: fetchUsers })
   - key 是缓存身份;同 key = 同数据

3. 写(POST/PUT/DELETE)用 useMutation 带缓存失效
   - 成功:queryClient.invalidateQueries({ queryKey: ["users"] })
   - 乐观更新:onMutate 在服务端响应前更新缓存

4. 本地 UI 状态(模态开、选标签)用 useState
   - 仅 ≥3 兄弟组件需同客户端状态时用 Zustand
   - 永不把服务端数据放 Zustand——属查询缓存

5. 依赖注入(主题、locale)用 React Context,非状态
   - 每状态变更都重渲染的 Context 致性能问题

示例

// 服务端状态——TanStack Query
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
export function UserList() {
  const { data: users, isLoading } = useQuery({ queryKey: ["users"], queryFn: fetchUsers });
  const qc = useQueryClient();
  const mutation = useMutation({
    mutationFn: deleteUser,
    onSuccess: () => qc.invalidateQueries({ queryKey: ["users"] }),
  });
  if (isLoading) return <Spinner />;
  return users.map(u => <UserRow key={u.id} user={u} onDelete={() => mutation.mutate(u.id)} />);
}

// 客户端状态——Zustand(仅跨组件 UI 状态)
import { create } from "zustand";
export const useUIStore = create<{ sidebarOpen: boolean; toggle: () => void }>((set) => ({
  sidebarOpen: false, toggle: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),
}));

常见问题

  • ⚠服务端数据存 useState 手动重取,丢缓存、去重和后台刷新。
  • ⚠一切用 Redux 因'我们熟悉',为开关加 200 行样板。
  • ⚠服务端状态放 Zustand,两组件显示同数据不同版本。
  • ⚠Context 持频繁变状态,每更新致每消费者重渲染。

最佳实践

  • ✓默认 staleTime 30-60 秒,重复导航不重取——用户感知即时页面加载。
  • ✓查询 key 用带变量数组(['user', userId])每实体独立缓存。
  • ✓hover/链接聚焦时预取下页数据,导航感即时。
  • ✓Zustand store 小而专注——每功能一 store,非全局 app store。