背景: Recoil
是 Facebook
推出的一款专门针对React
应用的状态管理库,在一定程度上代表了目前的一种发展趋势,在使用时觉得一些理念很先进,能极大地满足作为一个前端开发者的数据需求,本文对 Recoil
的这些特性做一个梳理。
根据官网的介绍,Recoil
的数据定义了一个有向图 (directed graph),状态的变更是通过改变图的根节点 (atom),再通过纯函数 (selector) 流向 React
组件。
同时 Recoil
的状态定义是增量和分布式的,增量意味着我们可以在用的时候再定义新的状态,而不必将所有状态提前定义好再消费。分布式意味着状态的定义可以放在任何位置,不必统一注册到一个文件中。这样的好处是一方面可以简化状态的定义过程,另一方面也可以很好地应用在 code-splitting 场景。
在一个应用中开启 Recoil
非常简单,只需要包裹一个 RecoilRoot
即可。
import { RecoilRoot } from 'recoil';
ReactDOM.render(<RecoilRoot> <App /></RecoilRoot>,root);
状态定义,原子和选择器
Recoil
允许使用 atom
和 selector
两个函数定义基础和推导状态。
atom
基本用法,这里定义了相关的原子属性,需要使用唯一 key
来描述这个 atom
。 Recoil
中不允许重复的 key 出现,包括后面提到的 selector
。
const firstNameAtom = atom({key: 'first name atom',default: ''
});
const lastNameAtom = atom({key: 'last name atom',default: ''
});
使用时通过 useRecoilState
这个 hooks 获取状态,可以看到它和 useState
很像,所以可以很轻松地将传统的React状态迁移到 Recoil
中。
function UserProfile() {
-const [firstName, setFirstName] = useState('');
+const [firstName, setFirstName] = useRecoilState(firstNameAtom);return (<div> { firstName } </div>);
}
很多时候我们只想获取数据而不想修改,或者反之,此时可以用语法糖 useRecoilValue
和 useSetRecoilState
function UserProfile() {const firstName = useRecoilValue(firstNameAtom);return (<div> { firstName } </div>);
}
Recoil
会根据哪里用到了这些状态自动建立一种依赖关系,当发生变更时 Recoil
只会通知对应的组件进行更新。
selector
的用法和 atom
很像,构造一个 selector
至少需要一个唯一的 key
和 get
函数。
const nameSelector({key: 'my name selector',get: ({ get }) => {return get(firstNameAtom) + ' ' + get(lastNameAtom);}
});
在 selector
中可以读写任意 atom
/ selector
,没有任何限制。只有 get
方法的 selector
是只读的,如果需要可写,也支持传入 set
方法。
const nameSelector({key: 'my name selector',get: ({ get }) => {return get(firstNameAtom) + ' ' + get(lastNameAtom);},set: ({ ge