Recoil 0.7.6
顯示旗幟以停用「重複原子鍵」檢查/記錄,原因是它在 NextJS 或使用 Fast Refresh 的某些開發環境中過於繁雜。(#733, #2020, #2046)
- 從 recoil 套件匯入
RecoilEnv
,並在程式碼中設定RecoilEnv.RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED = false
來停用檢查和記錄。 - 我們也支援 NodeJS 環境(例如 NextJs)中的
process.env.RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED=false
- 注意:這會停用所有重複原子鍵的檢查,包括合法的錯誤,請謹慎使用!
- 從 recoil 套件匯入
React 18 使用環境中對於不支援
useSyncExternalStore()
的巢狀 渲染器之權宜解決方案。(#2001、#2010)
Recoil 同步 0.2
- 為
listen
屬性 callback 匯出updateItems()
,搭配<RecoilSync>
使用,除了updateItem()
和updateAllKnownItems()
。(#2017、#2035) - 從網址中移除參數時,如果使用帶有
param
的位置queryParams
,會導致原子重設。如果原子可能與多個網址參數同步,這是一個輕微的破壞性變更。(#1900、#1976) - 如果偵測到
<RecoilURLSyncTransit>
的不穩定handlers
屬性,就新增一個開發人員警告。(#2044)
Refine 0.1.1
Recoil 0.7.5
- 修正開發期間使用 React 的快速重新整理時發生的
useRecoilSnapshot()
問題(#1891) - Chrome v104 開始,修改瀏覽器行為後,修復
useRecoilSnapshot()
和recoil-sync
的問題(#1943、#1936)
Recoil Sync 0.1
NM 程式套件 recoil-sync
的最初開源版本!Recoil Sync 提供附加函式庫,協助將 Recoil 狀態與外部系統同步。可透過選擇器或 useEffect()
實作簡單的 非同步資料查詢,或使用 原子效果 來雙向同步個別原子。recoil-sync
附加套件提供一些額外功能
- 批次原子交易 - 針對多個原子進行的更新可以與外部系統一起批次合併為單一交易。如果需要原子交易來保持相關原子的狀態一致,這項功能就很重要。
- 抽象且靈活 - 此 API 允許使用者指定要個別同步的原子,而不必描述同步機制。這讓元件可以在不變更實作的情況下,在不同環境中使用原子並與不同系統同步。例如,元件在作為獨立工具使用時,可能會使用會固定在 URL 上的原子,而當內嵌在其他工具中時,則會固定在自訂使用者資料庫中。
- 驗證和向下相容性 - 處理來自外部來源的狀態時,驗證輸入資料非常重要。當狀態持續超過應用程式的生命週期時,考量狀態先前版本的向下相容性也很重要。
recoil-sync
和refine
有助於提供這項功能。 - 原子到外部儲存體的複雜對應 - 原子與外部儲存項目之間可能不是一對一的對應。原子可能會移轉到使用較新版的項目,可能會從多個項目中提取道具,僅是某些複合狀態的一部分,或其他複雜的對應。
- 與 React Hooks 或道具同步 - 此函式庫允許將原子與無法從原子效果存取的 React hooks 或道具同步。
recoil-sync
函式庫也提供外部儲存體的內建實作,例如 與瀏覽器 URL 同步。
基本概念是,可以新增 syncEffect()
到您想要同步的每個原子,然後在 <RecoilRoot>
內新增 <RecoilSync>
來指定如何同步這些原子。您可以使用內建儲存體,例如 <RecoilURLSyncJSON>
、製作自己的,甚至可以將不同群組的原子與不同的儲存體同步。
範例
URL 固定
以下是一個簡單的範例 與瀏覽器 URL 同步原子
const currentUserState = atom<number>({
key: 'CurrentUser',
default: 0,
effects: [
syncEffect({ refine: number() }),
],
});
然後,只要在應用程式根目錄中包含 <RecoilURLSyncJSON>
,即可同步所有這些已標記的原子與 URL
function MyApp() {
return (
<RecoilRoot>
<RecoilURLSyncJSON location={{part: 'queryParams'}}>
...
</RecoilURLSyncJSON>
</RecoilRoot>
)
}
完成了!現在,這個 atom 會在初次載入期間依據 URL 初始化其狀態,任何狀態轉變都會更新 URL,而 URL 的更改(例如,返回按鈕)會更新 atom。在同步效果、儲存實作和URL 持久性指南中,請參閱其他更多範例。
精煉版 0.1
類型精煉和輸入驗證的@recoiljs/refine
函式庫,現已針對 Flow 和 TypeScript 初始開放原始碼版本!如果想要開始了解精煉,請參閱工具程式和檢查器核心概念的說明文件。
Recoil 同步函式庫利用精煉進行類型精煉、輸入驗證和升級類型以確保後向相容性。有關更詳細的資料,請參閱recoil-sync
說明文件。
我為什麼想使用精煉?
- 當您的程式碼遭遇
unknown
TypeScript 型別或mixed
Flow 型別值,而您需要聲明那些值具有特定的靜態型別時,精煉會派上用場。 - 精煉提供了一個 API,用於建立類型精煉的輔助程式功能,這些程式功能可以驗證未知值是否符合預期的型別。
- 精煉可以驗證輸入值,並從舊版本升級。
類型精煉範例
將未知型別強制轉換為強類型變數。assertion()
會在輸入不符合預期型別時傳回,而coercion()
則會傳回null
。
const myObjectChecker = object({
numberProperty: number(),
stringProperty: optional(string()),
arrayProperty: array(number()),
});
const myObjectAssertion = assertion(myObjectChecker);
const myObject: CheckerReturnType<myObjectChecker> = myObjectAssertion({
numberProperty: 123,
stringProperty: 'hello',
arrayProperty: [1, 2, 3],
});
後向相容範例
使用match()
和asType()
,您可以從舊版型別升級到最新版本。
const myChecker: Checker<{str: string}> = match(
object({str: string()}),
asType(string(), str => ({str: str})),
asType(number(), num => ({str: String(num)})),
);
const obj1: {str: string} = coercion(myChecker({str: 'hello'}));
const obj2: {str: string} = coercion(myChecker('hello'));
const obj3: {str: string} = coercion(myChecker(123));
JSON 分析範例
精煉會包裝JSON
,以提供內建的強類型分析器。
const myParser = jsonParser(
array(object({num: number()}))
);
const result = myParser('[{"num": 1}, {"num": 2}]');
if (result != null) {
// we can now access values in num typesafe way
assert(result[0].num === 1);
} else {
// value failed to match parser spec
}
Recoil 0.7.4
Recoil Relay 0.1
作為使用GraphQL的recoil-relay
資源庫的首次開放原始碼版本!
這個資源庫有助於 Recoil 執行類型安全的有效查詢,使用GraphQL和Relay資源庫。它提供可以輕鬆用 GraphQL 查詢的選擇器。這些查詢與 Recoil 資料流圖同步,讓下游選擇器可以從這些查詢中推導出狀態,它們可以依賴上游 Recoil 狀態,而且會自動訂閱 Relay 圖表中的任何變更。所有內容都會自動保持同步。
範例
GraphQL 查詢只要定義一個GraphQL 選擇器就可以簡單執行
const userNameQuery = graphQLSelector({
key: 'UserName',
environment: myEnvironment,
query: graphql`
query UserQuery($id: ID!) {
user(id: $id) {
name
}
}
`,
variables: ({get}) => ({id: get(currentIDAtom)}),
mapResponse: data => data.user?.name,
});
接下來像使用任何其他 Recoil 選擇器那樣使用它
function MyComponent() {
const userName = useRecoilValue(userNameQuery);
return <span>{userName}</span>;
}