跳至主要內容

Redux 常見問題:組織狀態

目錄

組織狀態

我必須將所有狀態都放入 Redux 中嗎?我應該使用 React 的 useStateuseReducer 嗎?

沒有「正確」的答案。有些使用者偏好將每個資料都保留在 Redux 中,以隨時維護應用程式的完整可序列化和受控版本。其他人則偏好將非關鍵或 UI 狀態(例如「此下拉式選單目前是否開啟」)保留在組件的內部狀態中。

使用區域元件狀態是沒問題的。作為開發人員,你的工作是決定哪些類型的狀態組成你的應用程式,以及每個狀態區塊應該存在於何處。找到一個適合你的平衡點,然後照著做。

一些用於決定哪些類型的資料應該放入 Redux 的常見經驗法則

  • 應用程式的其他部分是否關心此資料?
  • 你是否需要能夠根據此原始資料建立進一步的衍生資料?
  • 相同的資料是否用於驅動多個元件?
  • 你是否重視能夠將此狀態還原到特定時間點(例如,時間旅行除錯)?
  • 你是否想要快取資料(例如,如果狀態中已經有資料,就使用這些資料,而不是重新要求資料)?
  • 你是否想要在熱重新載入 UI 元件(在交換時可能會遺失其內部狀態)時保持此資料一致?

進一步資訊

文章

討論

我可以將函式、承諾或其他不可序列化項目放入我的儲存庫狀態嗎?

強烈建議你只將純粹的可序列化物件、陣列和基本型別放入你的儲存庫中。技術上有可能將不可序列化項目插入儲存庫中,但這樣做可能會破壞儲存庫內容的持續性和重新整理能力,並干擾時間旅行除錯。

如果你可以接受持續性和時間旅行除錯可能無法按預期運作,那麼你絕對可以將不可序列化項目放入你的 Redux 儲存庫中。最終,這是你的應用程式,如何實作取決於你。與 Redux 的許多其他事項一樣,只要確保你了解所涉及的權衡即可。

進一步資訊

討論

我該如何整理狀態中巢狀或重複的資料?

具有 ID、巢狀或關聯性的資料通常應以「正規化」的方式儲存:每個物件應儲存一次,以 ID 為鍵,而其他參照它的物件應僅儲存 ID,而不是整個物件的副本。可以將儲存區的各個部分視為資料庫,每個項目類型都有個別的「表格」。normalizrredux-orm 等函式庫可以在管理正規化資料時提供協助和抽象。

進一步資訊

文件

文章

討論

我應該將表單狀態或其他 UI 狀態放入我的儲存區嗎?

這個問題也適用於決定什麼應該放入 Redux 儲存區的 相同經驗法則

根據這些經驗法則,大多數表單狀態不需要放入 Redux,因為它們可能不會在元件之間共用。不過,這個決定總是取決於你和你的應用程式。你可能會選擇將一些表單狀態保留在 Redux 中,因為你正在編輯最初來自儲存庫的資料,或者因為你確實需要在應用程式中其他地方的其他元件中看到進行中的值。另一方面,將表單狀態保留在元件的本機可能更簡單,並且僅在使用者完成表單後才發送動作將資料放入儲存庫。

基於此,在大多數情況下,你可能也不需要基於 Redux 的表單管理函式庫。我們建議按此順序嘗試這些方法

  • 即使資料來自 Redux 儲存庫,也要從手動撰寫表單邏輯開始。這可能是你所需要的全部。(請參閱 Gosha Arinich 關於在 React 中使用表單的貼文,以獲得一些關於此方面的出色指導。)
  • 如果你決定手動撰寫表單太困難,請嘗試使用基於 React 的表單函式庫,例如 FormikReact-Final-Form
  • 如果你絕對確定你必須使用基於 Redux 的表單函式庫,因為其他方法不足夠,那麼你可能最終會想要查看 Redux-FormReact-Redux-Form

如果你在 Redux 中保留表單狀態,你應該花一些時間考慮效能特徵。在文字輸入的每個按鍵上發送動作可能不值得,你可能需要研究 緩衝按鍵以在發送之前保持變更為本機的方式。一如往常,花一些時間分析你自己的應用程式的整體效能需求。

其他類型的 UI 狀態也遵循這些經驗法則。經典的範例是追蹤 isDropdownOpen 旗標。在大多數情況下,應用程式的其他部分並不在乎這一點,因此在大多數情況下,它應該保留在元件狀態中。不過,根據你的應用程式,使用 Redux 來 管理對話方塊和其他快顯視窗、標籤、展開面板等是有道理的。

進一步資訊

文章