动机
出于兼容性和简便性的考虑,最好使用 React 的内置状态管理功能,而不要使用外部的全局状态。但 React 自身有一定的局限性:
- 只能通过状态提升至公共祖先来共享状态,但可能导致一颗巨大的树重新渲染。
- 上下文(context)只能存储一个值,而不能存储一组不确定的值,且每个值都有自己的使用者(consumers)。
- 这两种方式都很难将组件树的叶子节点(使用状态的地方)与组件树的顶层(状态必须存在的地方)进行代码分拆。
我们希望在保持 API 以及语义和行为尽可能接近 React 的同时,对上述问题进行改进。
Recoil 定义了一个正交有向图(directed graph orthogonal),并附加在 React 树中。状态的变化从该图的根(我们称之为 atom)开始,通过纯函数(我们称之为 selector)的方式传入组件。具体方式如下:
- 我们创建了无模板(boilerplate-free) API,其共享状态与 React 内部的状态拥有相同的 get/set 接口(如果需要,也可以使用 reducer 等)。
- 我们有与并发模式(Concurrent Mode)及其他 React 新特性兼容的可能性。
- 状态的定义是增量及分布式的,从而可以进行代码拆分。
- 可以用派生数据替换状态,而无需修改使用它的组件。
- 派生数据可以在同步与异步间切换,而无需修改使用它的组件。
- 我们可以将导航(navigation)视为一等公民(first-class concept),甚至可以对链接中的状态进行编码。
- 以向后兼容的方式持久保存整个应用程序的状态很容易,因此持久化保存的状态可以在应用程序更改之后继续存在。