React 状态管理进化史:从 setState 到 useSyncExternalStore

前端状态管理方案层出不穷——Redux、MobX、Zustand、Jotai、Recoil……它们之间到底是什么关系?各自解决了什么问题?本文从 React 状态管理的演进历史出发,梳理每个方案的核心思想和适用场景,帮你建立自己的状态管理选型框架。

React 状态管理进化史:从 setState 到 useSyncExternalStore

一切的起点:setState

2013 年 React 发布时,状态管理很简单——setState

class Counter extends React.Component {
  state = { count: 0 };
  render() {
    return (
      
    );
  }
}

这在组件内部工作得很好,但很快暴露了问题:跨组件共享状态怎么办?

答案是把状态"提升"到最近的公共祖先,然后通过 props 逐层传递。这就是 prop drilling——写起来繁琐,维护起来痛苦。

Redux 时代:单一状态树

2015 年,Redux 横空出世,带来了三个核心概念:

  1. Store:单一数据源,整个应用的状态存在一棵对象树里

  2. Action:描述"发生了什么"的普通对象

  3. Reducer:纯函数,接收旧状态和 Action,返回新状态

// Action
const increment = () => ({ type: 'INCREMENT' });

// Reducer
const counter = (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT': return state + 1;
    default: return state;
  }
};

// Store
const store = createStore(counter);
store.dispatch(increment());

Redux 解决了状态变化的可预测性问题——每次状态变更都有迹可循。但它也有代价:样板代码多,概念负担重。一个简单的计数器需要 action type、action creator、reducer、connect——四个文件。

原子化状态:Recoil 和 Jotai

2020 年 Facebook 推出 Recoil,提出了"原子"的概念:

const countAtom = atom({ key: 'count', default: 0 });

function Counter() {
  const [count, setCount] = useRecoilState(countAtom);
  return ;
}

每个 atom 是独立的状态单元,组件只订阅自己需要的 atom。这解决了 Redux 的"全局重渲染"问题——Redux 中任意状态变更会通知所有 connect 的组件,而 atom 只通知订阅了该 atom 的组件。

Jotai 沿用了 atom 概念但去掉了 key 的要求,API 更简洁。

轻量化革命:Zustand

Zustand 的核心理念是"Redux 的精华,去掉样板":

const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
}));

不需要 Provider 包裹、不需要 action type 常量、不需要 dispatch。直接调用函数即可。

回到原点:useSyncExternalStore

React 18 引入了 useSyncExternalStore——一个专门用于订阅外部 store 的 Hook。有意思的是,Zustand 和 Redux 的 React 绑定最终都基于这个 API。

这像是在说:React 终于"官方承认"了外部状态管理的必要性,并给了标准化的集成方式。状态管理的轮回完成了——从 React 内置到第三方繁荣,再回到 React 官方基础能力。

总结

没有"最好"的状态管理方案,只有最适合当前场景的:

  • 组件内部状态 → useState

  • 中等复杂度、需要中间件 → Zustand

  • 大型应用、需要时间旅行调试 → Redux Toolkit

  • 高频更新、细粒度订阅 → Jotai

选择的关键不是"哪个最流行",而是"哪个最匹配你当下的问题"。

如果本文对你有帮助,欢迎点赞收藏~ 有不同意见欢迎在评论区交流讨论。

聊天