:::info 🧾 目前处于草稿阶段 :::
Recoil 非常适合用于需要精心编排状态的应用场景,其写法比较简单,天然支持 Hooks,非常 React,且在 React18 之后支持 Transition 的新特性。
Recoil 的核心概念:https://recoiljs.org/docs/introduction/core-concepts
- Atom:原子化的状态,可以被全局共享和使用
- AtomEffects:处理状态变化的 SideEffects
- Selector:类似于 Redux Selector(Reducer) 和 MobX @Computed 的结合体
:::info
😎 将部分应用状态(ClientState)交给 Recoil,将服务端数据状态交给 React Query 最佳实践 就舒服了。
可以参阅:React 应用状态管理随记
:::
https://youtu.be/_ISAA_Jt9kI 👈 这个 Youtube 视频入门非常好。
:::success
💎 👇 这张图基本上概括了 Recoil 的设计思想,铺平的状态,映射到每一个子节点上,且可以 SHARE。
:::
使用全局 SnapShot 打印整体状态
https://recoiljs.org/docs/api-reference/core/Snapshot
class Snapshot {
retain(): () => void;
isRetained(): boolean;
// Accessors to inspect snapshot state
getLoadable: <T>(RecoilValue<T>) => Loadable<T>;
getPromise: <T>(RecoilValue<T>) => Promise<T>;
// API to transform snapshots for transactions
map: (MutableSnapshot => void) => Snapshot;
asyncMap: (MutableSnapshot => Promise<void>) => Promise<Snapshot>;
// Developer Tools API
getID: () => SnapshotID;
getNodes_UNSTABLE: ({
isModified?: boolean,
} | void) => Iterable<RecoilValue<mixed>>;
getInfo_UNSTABLE: <T>(RecoilValue<T>) => {...};
}
可以按需打印,可以在每一次变化的时候均打印全量或者按需打印即可。
增加 Logger 机制
为了让 Recoil 支持类似 Redux-Logger,让每一次 State 变化可追溯,我们可以在 useRecoilState 上做一层封装,打印出变更日志。
import { RecoilState, SetterOrUpdater, useRecoilState } from 'recoil';
import diff from 'diff';
export function useRecoilStateWithLog<T>(
recoilState: RecoilState<T>,
entity?: Function,
): [T, SetterOrUpdater<T>] {
const [state, setter] = useRecoilState(recoilState);
if (process.env.NODE_ENV === 'development') {
return [
state,
(u) => {
// 便于察觉变更的日志机制
// 类似于 Redux-Logger 的实现
// 提供对象的 diff 能力
console.groupCollapsed(
`[Recoil] set state [${recoilState.key}] with action from [${
entity?.name || entity?.toString() || 'unknown'
}]`,
);
if (typeof u === 'object') {
console.log('diff: ', diff(state as any, u as any));
}
console.trace('update to', u);
console.groupEnd();
if (setter) return setter(u);
return u;
},
];
} else {
return [state, setter];
}
}
最终实现在开发环境下,调用栈和状态 diff 的输出。
结合 React18 的 Transistion 特性
:::info 🛑 待 R18 发布之后再玩,现在太早了 … :::
Ref:https://recoiljs.org/blog/2022/01/28/0.6.0-release#react-18
Ref
- Github Repo 地址
- 外部比较好的介绍文章