React架构状态管理
2024 年的状态管理
·3 分钟阅读
格局已经变了
React Server Components 从根本上改变了状态的归属。「一切都是客户端状态」的旧心智模型不再适用。
核心洞察:大部分状态已经不属于客户端了。
决策框架
在引入任何库之前,先给状态分类:
是服务端数据? → RSC + fetch(零打包体积)
在 URL 里? → useSearchParams(可分享)
是表单? → useFormState(渐进式)
是局部 UI? → useState(够简单)
跨 3+ 组件共享? → Zustand(够轻量)
复杂且全局? → 考虑 Zustand slices
Server Components:默认选择
在 Next.js App Router 里,组件默认就是服务端的:
// 这个组件不会给客户端发送任何 JavaScript
async function UserProfile({ id }: { id: string }) {
const user = await db.user.findUnique({ where: { id } });
return (
<div>
<h1>{user.name}</h1>
<p>{user.bio}</p>
</div>
);
}没有 useEffect,没有加载状态,没有过期缓存。数据永远是新鲜的,因为它在请求时在服务端运行。
URL 状态:被低估的模式
'use client';
import { useSearchParams, useRouter } from 'next/navigation';
function Filters() {
const searchParams = useSearchParams();
const router = useRouter();
const setFilter = (key: string, value: string) => {
const params = new URLSearchParams(searchParams.toString());
params.set(key, value);
router.push(`?${params.toString()}`);
};
return (
<div>
<button onClick={() => setFilter('category', 'tech')}>
科技
</button>
</div>
);
}URL 状态可以分享、可以书签、可以前进后退。很多情况下,它比 Redux 更合适。
Zustand:够用的全局状态
当真的需要跨组件共享状态时,Zustand 是最轻量的选择:
import { create } from 'zustand';
const useStore = create((set) => ({
theme: 'dark',
setTheme: (theme: string) => set({ theme }),
}));
function ThemeToggle() {
const { theme, setTheme } = useStore();
return <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>切换</button>;
}零模板代码,零 Provider 嵌套,就这么简单。
实战建议
- 默认用 Server Components — 90% 的「状态」其实是服务端数据。
- 能用 URL 就别存客户端 — 过滤器、分页、排序都适合放 URL。
- Context 只用于依赖注入 — 别用它做数据缓存。
- Zustand 够轻,别想复杂了 — 大部分应用根本不需要 Redux 的复杂度。
- 状态要分层 — 服务端、URL、客户端全局、组件局部,各司其职。