跳到主要內容

快照類

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

取得快照

Hook

Recoil 提供以下 Hook,可依照目前狀態取得快照

建立新鮮快照

您也可以使用 snapshot_UNSTABLE() 工廠建置最新的快照。這可用於 React 內外的 測試 或評估選擇器。快照中的所有原子都將從它們的預設狀態開始,然而原子效果仍將執行而且可以初始化原子為動態值。snapshot_UNSTABLE() 也接受一個可初始化狀態的選用回撥,儘管原子效果初始化優先。另請注意儘管選擇器快取可透過 回撥 清除,但會在 Recoil 根節點和快照間共享。

讀取快照

相對於原子狀態而言,快照是唯讀的。它們可用於讀取原子狀態,並評估選擇器的衍生狀態。getLoadable() 提供 Loadable,其中包含這個快照中原子或選擇器狀態。getPromise() 方法可用於等待非同步選擇器的評估值,因此您可以看到值會根據靜態原子狀態為何。

範例

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

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

轉換快照

在某些情況下,您可能希望變異快照。儘管快照是不可變的,它們有方法透過一組轉換自身的方法,對應到一個不可變快照。Map 方法需要一個回撥,並傳遞一個 MutableSnapshot,它會在整個回撥中變異,並最終成為透過對應操作傳回的新快照。

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

注意與提供給可寫選擇器的 set 屬性的回撥一樣,set()reset() 具有相同的簽名,但它們僅影響新快照,而不是目前的狀態。

轉到快照

以下掛勾可用於將目前的 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

每個已提交狀態或已變異快照具有可通過 getID() 獲取之唯一不透明版本 ID。這可作為用於檢測是否已透過 useGotoRecoilSnapshot() 回到先前快照之途。

列舉 Atoms 和 Selectors

getNodes_UNSTABLE() 方法可做為重複處理該快照使用中之所有 atoms 和 selectors 之途。Atoms、selectors 和 families 可在任何時候產生。但前提是在確實使用下才會顯示在快照中。在不再使用 atoms 和 selectors 時,它們可能從後續狀態快照中移除。

可以使用選擇性 isModified 旗標,只回傳自上次交易以來已修改之 atoms。

偵錯資訊

getInfo_UNSTABLE() 方法提供 atoms 和 selectors 之額外偵錯資訊。所提供之偵錯資訊會持續更新,但可能包含

  • 可載入 - 擁有目前狀態之可載入項。與 getLoadable() 等方法不同,此方法完全不會變異快照。它提供目前狀態,並且不會初始化新 atoms/selectors,執行任何新 selectors 評估,或更新任何依賴項或訂閱。
  • isSet - 如果這是儲存於快照狀態中的 atom,且具有明確值,則為 True。如果這是 selector,或使用預設 atom 狀態,則為 False。
  • 已修改 - 如果這是自上次交易以來已修改之 atom,則為 True。
  • 類型 - 可能是 atomselector
  • 依賴項 - 這是針對此節點所依賴之 atoms 或 selectors 的反覆運算。
  • 訂閱 - 有關針對此快照,有哪些項目訂閱此節點的資訊。詳細資訊開發中。

此類似於 useGetRecoilValueInfo_UNSTABLE() 掛鈎,但在 Snapshot 中,根據狀態提供資訊,而非根據目前狀態。它無法提供與 Recoil 狀態之快照未相關聯之資訊,例如訂閱 React 組件。

狀態初始化

<RecoilRoot> 組件和 snapshot_UNSTABLE() 工廠採用選擇性 initializeState prop,用於透過 MutableSnapshot 初始化狀態。當您預先知道所有 atoms 時,且與必須同步與初始呈現地設定狀態的伺服器端呈現相容時,這麼做對於在持久狀態中載入狀態會很有幫助。對於逐個 atom 初始化/持續性,以及使用動態 atoms 的簡便性,請考慮atom 效果

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

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