前言
先说我的使用感受:不同于 redux 整个应用的 state 储存在一棵 object tree 中,recoil 将状态原子化并分散管理,这种状态拆分的细粒度和 hook 很搭,使用方式也和 hook 贴近(似乎代码量也更简洁,包括写 typescript)。
简单来讲 recoil 推崇的是分散式的状态管理,而 redux 是“三原则”之一的单一数据源。
FAQ
当我决定在新项目中使用 recoil 代替之前一直使用的 dva 时, recoil 官网都已经有官方的中文翻译了,所以使用起来也轻松很多。
下面是我在初次使用过程中,因文档没看全或一些其他问题导致的报错(不定时补充):
- 当你在更新 atom 的 useSetRecoilState 函数内写入更新其他 atom 的方法时,类似如下操作时:
const setChestnutOne = useSetRecoilState(chestnutOneAtom);
const setChestnutTwo = useSetRecoilState(chestnutTwoAtom);
setChestnutOne((bol) => {
setChestnutTwo(!bol);
return !bol;
});
会报如下错误:
Error: An atom update was triggered within the execution of a state updater function. State updater functions provided to Recoil must be pure functions.
原因就像报错的一样:提供给 Recoil 的状态更新器函数必须是纯函数。
如果你的 atom 需要跟踪依赖另一个 atom 的话,应该使用 Selector。
- 当直接修改储存在 atom 里对象的属性值时,类似下面的操作:
setChestnut((obj) => {
obj.value = 1;
return obj;
});
此时页面报了如下错误:
TypeError: Cannot assign to read only property 'value' of object '#<Object>'
此时你的 atom 需要声明 dangerouslyAllowMutability 为 true。因为为了安全,recoil 默认用 Object.freeze() 把对象冻结了。例:
export const chestnutAtom = atom({
key: 'chestnutAtom',
default: { value: 0 },
dangerouslyAllowMutability: true,
});
其他
在知乎上有一个关于 如何评价 Facebook 的 React 状态管理库 Recoil?的提问。虽然里面回答的时间节点大都是2020年5月份的,但感觉还是有收获的,感兴趣的可以看下。