摘要:相關狀態父組件傳遞給子組件的狀態。外部狀態狀態是可以從視圖庫中移出來的,然后可以使用提供者消費者模式把狀態重新連接回視圖庫。重新設計在我看來,重寫是有其必要性的,至少有以下個方面可以改進得更友好。
Redux 學習起來很困難?寫起代碼來很啰嗦?
一起來看看 Rematch 的作者對 Redux 的思考和簡化吧~
原文:《Redesigning Redux》, Shawn McKay
都過了這么多年了,狀態管理的問題難道不應該早就被解決了么?
個人直覺,開發者似乎都承認一個潛規則,那就是狀態管理問題似乎比想象的更復雜。在本文,我們將一起探討你可能已經遇到的問題:
我們真的需要一個狀態管理庫么?
Redux 的流行是否實至名歸?為什么?
我們是否能夠提出更好的狀態管理方案?如果是,怎么做?
真的需要狀態管理庫?前端開發并不僅僅是左右移動像素點。開發的真正藝術是掌握如何管理狀態。
簡單粗暴的答案是:狀態管理是復雜的,但是并非那么復雜。
以基于組件的視圖框架/庫為例,比如 React,讓我們來看看我們有哪些選擇:
1. 組件狀態存在于單個組件內部的狀態。在 React 中,就是指使用 setState 來更新的 state。
2. 相關狀態父組件傳遞給子組件的狀態。在 React 中,就是指通過屬性傳遞給子組件的 props。
3. 供給狀態保存在根提供者中、通過組件樹傳遞給消費者的狀態。在 React 中,對應于 context API。
大多數的狀態都是存在于視圖中的,因為它是用來反映用戶界面的。那么,對于反映底層數據和邏輯的其它狀態,又屬于誰呢?
如果把所有的狀態都填塞到視圖中,那么就嚴重違背了關注點分離原則。它會把你牢牢地綁在一個 JS 視圖庫中,使得代碼難以測試。更有甚者,可能會為你帶來大麻煩,因為你必須持續不斷的思考和調整狀態的存儲之處。
由于架構設計的改變,狀態管理會隨之變得復雜,并且通常很難判斷哪些組件需要哪些狀態。最簡單的做法是,在根組件上包含所有狀態。如果真要這么做的話,那么選用下一種方式會更好。
4. 外部狀態狀態是可以從視圖庫中移出來的,然后可以使用提供者/消費者模式把狀態重新連接回視圖庫。
Redux 也許是最流行的狀態管理庫。它在過去的 2 年時間里取得了巨大的流行度。那么,為什么一個簡單的庫會獲得如此之多的關注呢?
是因為它的性能更高么?其實并不是。實際上,它反而讓每一個必須處理的回調變得更慢了些。
那是因為它更簡單?也決定不是。
論簡單的話,那么純 JS 才是。正如 TJ 所說:
那為什么大家不直接使用 global.state = {} 呢?
為什么使用 Redux本質上,Redux 跟 TJ 所說的是同一件事,只不過 Redux 封裝了一些管道工具而已。
在 Redux 中,我們不能直接修改狀態。修改狀態的唯一方式是分發(Dispatch)一個動作(Action)到管道中,管道會自動根據動作去更新狀態。
從上圖可以看到,管道的中有 2 個監聽器集合:中間件(Middleware)和訂閱(Subscription)。中間件一些是監聽動作的函數,用來處理類似日志記錄、開發工具和發起服務請求等功能。訂閱則是一些用來廣播狀態變更的函數。
最后,合成器(Reducer)函數負責把狀態變更拆分成更小、更模塊化、更容易管理的代碼塊。
和使用一個全局對象相比,Redux 確實簡化了開發過程。
綜上,我們可以把 Redux 看成是一個全局對象,該對象不僅提供了狀態更新前/后鉤子,而且能夠以簡單的方式合成新狀態。
不覺得 Redux 過于復雜么?的確過于復雜。在平時的開發過程中,有一些不可否認的跡象,可以用來判斷框架 API 是否需要改進。這些跡象可以歸納為下面這個公式:
其中,節省的時間是指使用該框架來開發所消耗的時間,學習的時間則是閱讀框架文檔、學習教程和掌握新概念的總時間。
Redux 本身是個精簡的庫,但是其學習曲線卻很陡峭。雖然有不少開發者能夠克服深入學習函數式編程的困難并從 Redux 獲益良多,但是也有很多開發者望而卻步,寧愿重新使用 jQuery。
在 jQuery 中,你并不需要理解什么是 “comonad”,也沒必要理解通過函數組合來管理狀態。
任何框架或者庫的目的都應該是把復雜的事物抽象得更加簡單。
當然我這么說并不是想指責 Redux 的作者 Dan Abramov 。Redux 在其剛誕生初期就已經變得非常流行,沒有足夠的時間來精雕細琢。
我們怎么能隨便重構一個已經被成千上萬開發者使用的庫呢?
我們又怎么能合理發布會影響到不計其數項目的重大變更呢?
沒人可以。但是我們可以提供更好的支持,比如完善文檔、推廣視頻教程和擴大社區等。在這些方面,Dan Abramov 確實做得很棒。
又或者,還有另一種方式可以改變現狀。
重新設計 Redux在我看來,重寫 Redux 是有其必要性的,至少有以下 6 個方面可以改進得更友好。
1. 初始化過程讓我們來看看一個基本的 Redux 初始化過程,如下圖左邊所示:
很多開發者走到這里一步就開始止步了,簡直是一看三不知。什么是 chunk ?compose 又是什么鬼?一個函數還能這么使用?
如果 Redux 是基于配置而不是函數組合的話,那么像右邊那樣的初始化過程明顯看起來更加合理。
2. 簡化狀態合成器Redux 中的狀態合成器能夠使用一個 switch 來代替多個不必要的 switch 。
假如狀態合成器是根據動作的類型來匹配的,那么我們可以用逆向思維,把合成器變成一個接受 state 和 action 兩個參數的純函數。也許還可以更簡單些,我們可以把動作規劃化,并且只傳遞狀態和一個數據載荷。
3. 使用 Async/Await 代替 Thunks在 Redux 中,Thunks最通用的做法就是用來創建異步動作。從多角度來看,這種用法更像是一個聰明的黑客所采用的用法,而不是一種官方推薦的用法。我們一步一步來看:
首先分發了一個動作,然而實際上卻是一個函數而不是期望的對象
Thunk 中間件檢查每一個動作,看它是否是一個函數
如果是函數,那么中間件調用該函數,同時把 dispatch 和 getState 方法傳參進去
真的需要這樣么?把一個簡單的動作在運行時識別為對象、函數甚至是 Promise,這難道不是糟糕的實踐么?
如上圖右邊所示,難道我們就不能只使用 async/await ?
4. 兩種類型的動作如果我們認真想想的話,確實有兩種類型的動作:
合成器動作(Reducer action): 觸發合成器然后改變狀態
副作用動作(Effect action):觸發一個異步動作。這可能也稱為合成器動作,但是異步函數其實并沒有直接改變任何狀態。
因此,把這兩種類型的動作區分開來會更有用,同時也不容易與 Thunks 搞混。
5. 不再需要定義動作類型變量為什么我們的標準實踐要把動作生成器和狀態合成器區分開來呢?能否只用其中一個呢?改變其中一個又是否會影響到另一個?
在我看來,動作生成器和狀態合成器就是硬幣的兩個面。
const ACTION_ONE = "ACTION_ONE" 可以說是把動作生成器和狀態合成器分開的冗余產物。如果我們把這兩者合二為一,那么就不會有那么多文件專門導出這些類型字符串了。
6. 合二為一的合成器按照使用方式,把 Redux 中所涉及的概念進行合并分組,那么我們可以得出下面這個更簡單的模式。
在這種模式中,狀態合成器是可以自動確定與之對應的動作生成器。因為,此時狀態合成器可以自動變成動作生成器。
通過簡單的命名約定,以下行為都會變得可預測:
如果狀態合成器命名為 increment,那么動作類型就是 increment。更好的做法是加上命名空間: count/increment。
每個動作都通過 payload 屬性來傳遞數據。
這樣的話,對于 count.increment,我們就可以自動的從狀態合成器推導出動作生成器。
好消息:更棒的 Redux以上的通電就是我們創建 Rematch 的原因。
Rematch 對 Redux 進行了封裝,提供更簡單的 API,但又不失任何可配置性的特點。
下面是一個完整的使用例子:
我已經把 Rematch 應用在生成環境中有好幾個月了。作為小白鼠,我的體驗是:
狀態管理從未變得如此簡單、高效。
Redux 并沒有被拋棄,而且也不應該被拋棄。
只是,我們應該以更低的學習成本,更少的樣板代碼和更少的認知成本,來擁抱 Redux 背后的簡單哲學。
趕緊試一試 Rematch 吧!
萬一一不小心你就愛上它了呢?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95498.html
摘要:應用這說明并不是單指設計給用的,它是獨立的一個函數庫,可通用于各種應用。在數據流的最后,要觸發最上層組件的,然后進行整體的重新渲染工作。單純在的對象上是沒有辦法使用,要靠額外的函數庫才能這樣作,這是一定要使用類似像這種函數庫的主要原因。 Redux的官網中用一句話來說明Redux是什么: Redux是針對JavaScript應用的可預測狀態容器 這句話雖然簡短,其實是有幾個涵義的: ...
摘要:沿著管道有兩組偵聽器中間件和訂閱。中間件是可以偵聽傳入的動作的函數,支持諸如,或偵聽器之類的工具。將視為一個帶有更新前更新后鉤子的全局對象,以及能夠以簡單的方式合成新狀態。應將兩者視為一體,并且不再需要文件導出類型的字符串。 難道現在狀態管理不是一個可以解決的問題嗎?直觀地說,開發人員似乎知道一個隱藏的事實:狀態管理的使用似乎比需要的更困難。在本文中,我們將探討一些你可能一直在問自己的...
摘要:是一種前端狀態管理架構思想,專門解決軟件的結構問題。基于的設計思想,出現了一批前端狀態管理框架。他們給出了一些庫用于實現的思想,并在的基礎上做了一些改進。在這些框架里,當前最熱門的莫過于和了。 Flux Flux是一種前端狀態管理架構思想,專門解決軟件的結構問題。 基于Flux的設計思想,出現了一批前端狀態管理框架。他們給出了一些庫用于實現Flux的思想,并在Flux的基礎上做了一些改...
摘要:本周精讀內容是重新思考。數據流對數據緩存,性能優化,開發體驗優化都有進一步施展的空間,擁抱插件生態是一個良好的發展方向。 本周精讀內容是 《重新思考 Redux》。 1 引言 《重新思考 Redux》是 rematch 作者 Shawn McKay 寫的一篇干貨軟文。 dva 之后,有許多基于 redux 的狀態管理框架,但大部分都很局限,甚至是倒退。但直到看到了 rematch,總算...
摘要:關于的思考是一種前端狀態管理架構思想,專門解決軟件的結構問題。他們給出了一些庫用于實現的思想,并在的基礎上做了一些改進。在這些框架里,當前最熱門的莫過于和了。 關于Flux,Vuex,Redux的思考 Flux是一種前端狀態管理架構思想,專門解決軟件的結構問題。基于Flux的設計思想,出現了一批前端狀態管理框架。他們給出了一些庫用于實現Flux的思想,并在Flux的基礎上做了一些改進。...
閱讀 1291·2021-09-22 15:00
閱讀 3309·2019-08-30 14:00
閱讀 1220·2019-08-29 17:27
閱讀 1220·2019-08-29 16:35
閱讀 689·2019-08-29 16:14
閱讀 2042·2019-08-26 13:43
閱讀 2117·2019-08-26 11:35
閱讀 2309·2019-08-23 15:34