人人都会AI编程

Recoil:原子化状态与派生状态

更新时间:2026-07-11

Recoil 是 Facebook 推出的一个实验性状态管理库,专为 React 设计。它的核心理念是将状态拆分为一个个独立的原子(Atom),组件可以精确订阅它们需要的原子,当原子更新时,只有订阅了该原子的组件才会重渲染。基于原子,Recoil 提供了派生状态(Selector),用于计算衍生数据或异步获取数据,同样具备细粒度订阅特性。

核心概念

Atom
Atom 是最小的状态单元,每个 Atom 存储一个独立的值,可以被多个组件共享。当 Atom 的值发生变化时,所有订阅它的组件会自动重新渲染,无需手动通知。

import { atom } from 'recoil';

// 定义原子
export const todoListState = atom({
  key: 'todoListState', // 唯一标识
  default: [],          // 初始值
});

在组件中读写 Atom 就像使用 useState 一样简单:

import { useRecoilState } from 'recoil';

function TodoList() {
  const [todos, setTodos] = useRecoilState(todoListState);
  // ...
}

Selector
Selector 是派生状态,可以基于一个或多个 Atom 或其他 Selector 计算出一个新值。当依赖的原始状态变化时,Selector 会自动重新计算,且只有订阅该 Selector 的组件才会重渲染。Selector 也支持异步逻辑。

import { selector } from 'recoil';

// 派生状态:统计待办事项数量
export const todoStatsSelector = selector({
  key: 'todoStatsSelector',
  get: ({ get }) => {
    const todos = get(todoListState);
    return {
      total: todos.length,
      completed: todos.filter(t => t.done).length,
      active: todos.filter(t => !t.done).length,
    };
  },
});

组件使用 Selector 与使用 Atom 类似:

function TodoStats() {
  const stats = useRecoilValue(todoStatsSelector);
  return <div>已完成: {stats.completed}</div>;
}

为什么选择 Recoil?

  • 细粒度渲染:组件只关注自己需要的那一部分状态,避免全局 store 变化导致的全量重渲染。
  • 简洁的 APIuseRecoilStateuseRecoilValueuseSetRecoilState 等钩子与 React 的 useState 非常接近,学习成本低。
  • 懒加载与异步:Selector 天然支持异步数据请求,无需额外中间件。
  • 可组合性:可以将多个 Selector 组合在一起构建复杂的数据依赖图,类似电子表格的公式。

适用场景与局限性

Recoil 很适合需要细粒度状态控制、频繁更新的中等规模应用,尤其是当 Context 性能瓶颈明显或 Redux 觉得过于繁琐时。但它仍处于早期阶段,社区生态不如 Redux 成熟,对于非常大的应用,可能需要额外关注原子依赖图的组织。目前 Recoil 已停止活跃开发,新项目可考虑 Jotai 作为轻量替代,但 Recoil 的设计思路深刻影响了后续原子化状态库的演进。