跳至主要內容

Recoil 0.0.11

·閱讀時間 6 分鐘

我們今天將發布 Recoil 0.0.11。它包含修正的錯誤、新功能、更佳的效能,以及並發模式的實驗性相容性。非常感謝為此版本做出貢獻的所有人!

並發模式的實驗性支援

Recoil 現在支援與 React 的實驗性版本搭配使用的並發模式。請試試看並回報任何問題!

並發模式可提供更流暢、更一致的使用者體驗,是 React 的未來。但迄今為止,它與任何類型的外部狀態都不相容。這是因為在並發模式中,渲染可以隨著時間分散:React 可以暫停元件的渲染,然後稍後從它離開的地方繼續,從它已經建立的部分元件樹開始

React pauses while rendering a tree of components. Some components are rendered before the pause while others are rendered after the pause.

這會導致外部狀態出現問題。由於 React 現在放棄了控制流程,因此在渲染開始和完成之間可能會發生任何事。如果在此期間外部狀態發生變更,將導致使用者介面不一致,因為較早渲染的元件會觀察到舊狀態,而較晚渲染的元件會觀察到新的狀態

If components depend on some external state, and that state changes while rendering is paused, then components rendered before the pause will observe the old state, while components rendered after the pause will observe the new state.

不一致性可能會導致應用程式崩潰等問題。

Recoil 現在利用 React 中的實驗性 API 來處理這種情況,它會在 Recoil 狀態於某次渲染程序執行期間變更時重新使用新樹展開。這些 API 也讓 Recoil 更為有效率,並在元件首次掛載時無需重新渲染。

請勿於製作環境中使用 React 的實驗性版本。並且無論您使用哪個版本的 React 或狀態管理程式庫,請始終在 useEffect() 勾子中保留副作用,而非在渲染過程中進行,以避免錯誤!(@davidmccabe@bvaughn

效能

多項調整讓 Recoil 的效能獲得提升。先前的 Recoil 在某些情況下必須重新渲染元件,像是從具有未知依賴項目的選取器中讀取,或是從已從外部儲存體初始化的原子中讀取時。現今,Recoil 再也不會執行第二次渲染來回應讀取原子或選取器。(@davidmccabe

接著,Recoil 搭配 React 的experimental版本使用時,不再需要於元件初始掛載時執行第二次渲染。另外,當其他原因(非原子或選取器變更)造成重新渲染時,Recoil 也無須再處理原子或選取器值搜尋的工作。(@davidmccabe@bvaughn)。

諸如 useRecoilValue()useRecoilState() 之類的基本勾子已最佳化,並提升了約 8×的執行速度。它們現在執行所需的時間通常短於 useState() 2×倍。這大幅提升了使用許多元件中大量原子的應用程式效能。(@davidmccabe

Recoil 會遞迴凍結原子和選取器的內容。此舉可防止錯誤,但對於大型物件來說會很慢。目前僅會在開發組建中執行。(#361 @drarmstr)

Recoil 現在可以在您將原子設為它已設定的值或在已重設的情況下重設原子時,避免重新渲染元件或重新評估選取器。(#399#386 @drarmstr).

最後,此版本也修正了在先前版本中引發的記憶體洩漏問題。如果您發現頻繁更新原子的應用程式效能不佳,這很有可能是原因。(#471 @davidmccabe)

類別和封裝

除了 TypeScript 外,Flow 類別 現在已隨套件一起匯出。Flow 是 Facebook 使用的類別系統,也是 Recoil 實際編寫的語言。(#338#468#541 @Brianzchen@Komalov@mondaychen)

TypeScript 打字也得到了改進(#492#545#548#568#575 @csantos42@SergeyVolynkin@drarmstr@hachibeeDI)。

除了 NPM 套件外,我們現在透過 CDN 提供Common JS 和 UMD 模組#413 @mondaychen@pocket7878)。

支援多個 React Root

現在你可以在多個 React 根目錄之間分享狀態。例如,如果你的應用程式同時使用 React DOM 和另一個渲染器(例如 ThreeJS),現在就可以在它們之間分享 Recoil 狀態。如同始終使用多個 React 根目錄時一樣,它們可能會暫時不同步。(#298#516 @drarmstr@inlet)

開發工具 API

此版本包含專供開發工具使用的實驗性 API。我們正在內部建立一組開發工具,而且也進行了多個開源專案。我們發佈這些 API 以協助驗證其設計。(@drarmstr)

其他新的 API

現在您可以將 Promise 用作原子的預設值。讀取時將如同非同步選取器。(@drarmstr

錯誤修正

此更新包含許多與測試基礎結構,以及開源和 Facebook 內部環境差異相關的修正。(#368#360#362#363#392#431#402#538#539#549#561#576 @aaronabramov@Komalov@drarmstr@jacques-blom@mondaychen@dsainati1@csantos42@behnammodi@habond@benhalverson)。

它也修正了在快照中使用多個 <RecoilRoot> 或預先載入選取器時的錯誤(#534 @davemccabe).

重大變更

此更新可能會中斷某些未透過 react-test-utils 中的 act() 函式來執行影響 React 元件行為的 動作,而導致這些測試無法通過。這些測試有時會運用 Recoil 的額外錯誤處理而通過。使用 act() 來修正所有此類測試。

如果提供給 Recoil 的狀態更新函式在其本身執行期間導致另一個原子更新,Recoil 現在會引發例外狀況。狀態更新函式應為純函式,所以這一直違反 API 合約。但在某些情況下,此種行為過去依然可行,但現在已經不行了。執行此動作的程式碼可變更為使用 useRecoilCallback() 來執行效果。

未來工作

在未來的版本中,Recoil 將會自動釋放不再使用的 atom 和 selector 所佔用的記憶體,而且在較大量的 atom 中執行效能會更好。(@davidmccabe

我們也在開發將 Recoil atom 與外部資料來源(例如 URL、本機儲存或伺服器)同步的 API。(@drarmstr

開發人員工具正在開發中。(@maxijb@habond@drarmstr

感謝您閱讀到這裡並使用 Recoil!最近即將推出更多版本。