標籤:

redux中所有state都要放在store里嗎?

初學redux,感覺有些state也可以直接放在組件里,請問是所有state都要放在store里嗎?為什麼?


前 Flux 用戶, 現 ClojureScript 用戶.

React 的 Single Application State 可以追溯到 ClojureScript 的 Om 框架, Om 就是一個 React 的 ClojureScript 的綁定, 可以在裡邊直接調用 React API. 關於 Om 的具體細節我沒有全摸清楚, 大體上由於 ClojureScript 當中 Immutable data 用得很輕鬆, 加上 Lisp 風格的 data tree, 所以比較擅長把 global data 管理好.

Redux 往這邊面設計的. 從理念上講, 無論是 MVC 還是 uni-directional data flow, 其中的數據都是全局存儲在一起的, 然後發散到 component tree 的各個枝葉上. 這樣能帶來一些好處, 首先是數據在全局管理便於保證一致性, 實際上也相當於回到的傳統網站開發的所有數據存儲在資料庫當中的做法. 其次, 數據存儲在全局也能帶來開發當中的好處, 可以緩存全局狀態, 而直接替換掉渲染代碼. 所以 Redux 會推薦全局管理數據.

就像前面那個答案說的, 組件狀態成了一個比較奇怪的東西. 在 React 的實現當中, 它是局部狀態, 也就意味著 Redux 中的 Store 無法管理這部分狀態, 另一方面在代碼熱替換的過程當中 component states 一般會丟失, 除非用 react-hot-loader 之類的方案強行存儲和恢復狀態. 相當於是為了使用方便而遺留的一個問題. 那麼我建議在 React 應用當中, component state 依然採用局部狀態直接管理, 而不是存儲在 Store 當中. 畢竟在維護層面上講, 把 View State 存儲到 Store 本身就是可疑而且麻煩的.

我在研究 Respo (http://respo.site) 這個基於 ClojureScript 的 Virtual DOM 的方案時想到應該有更好的方案, 也就是把 component states 也用 data tree 存儲起來, 當然這種過程由框架來完成, 用戶編寫 React 組件時只需要提供更新的函數即可. 這樣也就能保證兩方面的好處都存在, 既是在組件上編寫狀態, 又是能在熱替換過程當中持有數據. 希望 React 社區有探索過類似的方案.


這類問題最好的方式是去Redux Github issues里找,作者已經有回答了。

Use React for ephemeral state that doesn"t matter to the app globally and doesn"t mutate in complex ways. For example, a toggle in some UI element, a form input state. Use Redux for state that matters globally or is mutated in complex ways. For example, cached users, or a post draft.

Sometimes you"ll want to move from Redux state to React state (when storing something in Redux gets awkward) or the other way around (when more components need to have access to some state that used to be local).

The rule of thumb is: do whatever is less awkward.


主要適用組件之間共享狀態:

1. 組件之間可能被共享的數據,使用redux!

2. 配置信息(token、API)盡量單獨記錄,或者維護在非視圖組件內部

3. 組件內部如無明確外部交互,優選state!複雜交互組件還需內部創建redux實例(甚至多個)

4. 通過mapStates組件之間共享數據,盡量避免監聽他人事件

5. 切莫過度依賴redux,狀態樹盡量簡單結構,btw:you-might-not-need-redux


不需要,redux的store一個優點是可以方便組件之間共享狀態以及通訊。但是對於一些只局限在組件內部的狀態,完全無需存在store當中,這樣不但沒有必要,反而會增加複雜度。

在redux官方文檔中有一個Todo List的例子,其中的input組件的內部狀態就是自己維護,沒有存在store當中,可以很好的說明這一點原則:Example: Todo List


雖然沒怎麼用過redux,但是最近在用vue,道理類似,感覺不會被多次調用或共享的基本不用放在 vuex里,一是增加代碼複雜度,二是過度使用vuex 會導致 難於維護 !當然這個度要根據實際項目 模塊功能 具體在看!


當然不用。前端的一些界面的按鈕的狀態,下拉菜單的狀態可以存在當前組件的State中(構造函數里生成),後端非同步訪問數據的結果最好存在Redux的store中,方便別的組件或別的界面訪問。Redux中的Store和React中的State沒有直接的關係,兩個概念。


依照 redux 的理念,答案是肯定的。全局唯一狀態樹的好處是容易記錄、跟蹤、調試、復現等,如果你的程序在 redux store 以外還有狀態,那上面這些優點就沒有了。redux 搞得這麼繁瑣,犧牲這麼大,如果沒有獲得相應的好處,那還用 redux 幹什麼?買櫝還珠啊。

redux 的問題在於太繁瑣,簡單的事情用了太多代碼,讓人產生偷懶用組件本地狀態的動力。

我有一個方案,大致做法是用一個和組件樹結構一致的狀態樹,而且是全局單一的,和 redux 那種鼓勵攤平的不同。還沒有完善,一些問題還沒考慮好,例如如何維持快速檢測變動的特性,如何處理帶參數的子狀態等等。


根據業務場景適當區分展示state和非展示的數據,例如一些在後端渲染給頁面的數據TOKEN,REQUEST URL等信息,其不會造成頁面任何變化,完全可以將其放在全局WINDOW上的一個對象統一管理更方便! 否則就要放在redux state通過PROPS傳遞 或 CONTEXT獲取,很是麻煩!

在某些場景改變這些非展示數據,還可以避免REACT-REDUX的淺比較或組件的DIFF!

個人覺得不要太死的使用REDUX,完全可以根據自己項目,業務場景來劃分!


沒用過 不過參考瀏覽器dom 實現 state應該可以從外部改變內部狀態 所以不是所有組件屬性都應該是state


可以都放在Store里,也可以不放。你覺得怎麼維護簡單怎麼放。


對於是否要維護一些不在redux store里的小狀態,我記得redux的一個co-author的原話是

do what is less awkward

果然是everything depends on if(攤手


推薦閱讀:

TAG:Redux |