跳至主要内容

Snapshot 类

一个 Snapshot 对象表示 Recoil 原子 状态的不可变快照。它旨在标准化观察、检查和管理全局 Recoil 状态的 API。它主要用于开发工具、全局状态同步、历史导航等。

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 state to a new immutable Snapshot
map: (MutableSnapshot => void) => Snapshot;
asyncMap: (MutableSnapshot => Promise<void>) => Promise<Snapshot>;

// Get a StoreID similar to useRecoilStoreID()
getStoreID: () => StoreID;

// Developer Tools API
getID: () => SnapshotID;
getNodes_UNSTABLE: ({
isModified?: boolean,
} | void) => Iterable<RecoilValue<mixed>>;
getInfo_UNSTABLE: <T>(RecoilValue<T>) => {...};
}

function snapshot_UNSTABLE(initializeState?: (MutableSnapshot => void)): Snapshot

获取快照

钩子

Recoil 提供以下钩子来获取基于当前状态的快照

创建新的快照

您也可以使用 snapshot_UNSTABLE() 工厂构建新的快照。这可用于 测试 或在 React 上下文之外评估选择器。快照中的所有原子都将从其默认状态开始,但原子效果仍将运行,并且可以将原子初始化为动态值。snapshot_UNSTABLE() 还会接受一个可选回调来初始化状态,但原子效果初始化优先。另请注意,选择器缓存是在 Recoil 根和快照之间共享的,但可以使用 回调 清除它们。

读取快照

快照在原子状态方面是只读的。它们可以用于读取原子状态和评估选择器的派生状态。getLoadable() 提供一个包含此快照中原子或选择器状态的 LoadablegetPromise() 方法可用于等待异步选择器的已评估值,以便您可以查看基于静态原子状态的值将是什么。

示例

function MyComponent() {
const logState = useRecoilCallback(({snapshot}) => () => {
console.log("State: ", snapshot.getLoadable(myAtom).contents);

const newSnapshot = snapshot.map(({set}) => set(myAtom, 42));
});
}

转换快照

在某些情况下,您可能希望更改快照。虽然快照是不可变的,但它们具有方法可以使用一组转换将自身映射到新的不可变快照。map 方法接受一个回调,该回调传递给 MutableSnapshot,MutableSnapshot 在整个回调过程中发生更改,并将最终成为映射操作返回的新快照。

class MutableSnapshot {
set: <T>(RecoilState<T>, T | DefaultValue | (T => T | DefaultValue)) => void;
reset: <T>(RecoilState<T>) => void;
}

请注意,set()reset() 的签名与可写选择器的 set 属性提供的回调相同,但它们只会影响新快照,而不是当前状态。

转到快照

以下钩子可用于将当前 Recoil 状态更新为与提供的 Snapshot 相匹配

异步使用快照

快照仅在获取它们的回调的持续时间内保留。要在之后使用它们,应使用 retain() 明确保留它们。

test('My Test', async () => {
const testSnapshot = snapshot_UNSTABLE();
const releaseSnapshot = initialSnapshot.retain();

try {
await something;
... use testSnapshot ...
} finally {
releaseSnapshot();
}
});
function MyComponent() {
const myCallback = useRecoilCallback(({snapshot}) => () => {
const release = snapshot.retain();
setTimeout(() => {
... use snapshot ...
release();
}, 1000);
});

...
}

请注意,异步选择器必须由某个 <RecoilRoot>Snapshot 积极使用,才能确保它们不会被取消。如果您只通过快照访问异步选择器,则必须保留它们才能保证您可以观察到已解析的值。

开发者工具

快照提供一些方法,可用于 构建开发工具 或使用 Recoil 进行调试功能。此 API 仍在不断发展,因此被标记为 _UNSTABLE,因为我们正在努力开发最初的开发工具。

快照 ID

每个提交的状态或更改的快照都有一个唯一的非透明版本 ID,可以通过 getID() 获取。这可用于检测何时使用 useGotoRecoilSnapshot() 返回到之前的快照。

枚举原子和选择器

getNodes_UNSTABLE() 方法可用于迭代此快照中使用的所有原子和选择器。原子、选择器和族可以在任何时间创建。但是,它们只会在实际使用时出现在快照中。如果原子和选择器不再使用,它们可能会从后续状态快照中删除。

可以指定一个可选的 isModified 标志,仅返回自上次事务以来已修改的原子。

调试信息

getInfo_UNSTABLE() 方法提供了有关原子和选择器的其他调试信息。提供的调试信息正在不断发展,但可能包括

  • loadable - 包含当前状态的 Loadable。与 getLoadable() 等方法不同,此方法根本不会更改快照。它提供当前状态,不会初始化新的原子/选择器,执行任何新的选择器评估,或更新任何依赖项或订阅。
  • isSet - 如果这是存储在快照状态中的具有明确值的原子,则为 True。如果这是选择器或使用默认原子状态,则为 False。
  • isModified - 如果这是自上次事务以来已修改的原子,则为 True。
  • type - atomselector 之一
  • deps - 此节点所依赖的原子或选择器的迭代器。
  • subscribers - 此快照中订阅此节点的内容的相关信息。详细信息正在开发中。

这类似于 useGetRecoilValueInfo_UNSTABLE() 钩子,但提供基于 Snapshot 中状态的信息,而不是当前状态。它无法提供与 Recoil 状态快照无关的信息,例如订阅的 React 组件。

状态初始化

<RecoilRoot> 组件和 snapshot_UNSTABLE() 工厂接受一个可选的 initializeState 属性,用于通过 MutableSnapshot 初始化状态。这对于在您事先知道所有原子时加载持久状态很有用,并且与服务器端渲染兼容,在服务器端渲染中,状态应与初始渲染同步设置。对于每个原子初始化/持久化以及轻松使用动态原子,请考虑 原子效果

function MyApp() {
function initializeState({set}) {
set(myAtom, 'foo');
}

return (
<RecoilRoot initializeState={initializeState}>
...
</RecoilRoot>
);
}