博客 / 詳情

返回

大型項目數據狀態管理摸索

講一個悲傷的故事

本來這篇文章應該是上週寫完的。

故事發生在一週前,我在segmentfault在線編輯文章,寫了差不多兩個小時,在貼了一張圖片失敗之後,然後ctrl+z撤銷了一步,結果整個文檔被瞬間清空了,編輯器還自動保存了清空態。

這一刻,有點心涼,彷彿突然被澆了一桶冷水。

第一時間,打開瀏覽器控制枱,去翻緩存,結果localStorage裏面空空如也,當時就感覺希望不大了,幻想着他們服務端能保存某個時刻的記錄。

微信聯繫了他們的客服小姐姐,晚飯後回覆我:“技術人員下班了,明天幫忙查看,問我急不急?”。還能怎樣?開發何必為難開發,當時就放過了她。

第二天,經過他們一番追蹤,服務端沒有任何記錄......

結局就是現在這樣,我再重新寫一遍。

通過這個事件,也可以看出,segmentfault的數據狀態管理機制還是有缺陷的,容錯機制不太好,至少緩存機制不太行,共勉!

概述

有個頭痛的問題,什麼是愛情?

噢噢,狀態錯亂了,“狀態混亂”就這個頭痛的問題。

隨着前端應用的規模越來越龐大,業務複雜度直線拉昇。狀態管理也成為了重中之重,DDD領域驅動模型也逐漸盛行。

隨着項目發展,單元測試也變成了很重要的一個環節,隨着業務邏輯複雜度的增加,問題關注點直接爆炸,人力心智負擔越來越高。

所以不管是 為了更好地開發模型 還是 更容易的單元測試,如何更好地管理數據狀態都 成了一個 核心環節。

比如,領域狀態 要和 UI狀態分離;依照DDD領域驅動模型構建 數據Store,而不是依據UI來構建。

狀態數據構建 是 全局的還是 局部的,衍生數據 如何自動生成,副作用變更邏輯如何書寫?

數據邏輯 如何 和 UI視圖 解耦,又如何方便注入UI使用,怎樣進行方便的通信?

社區有那麼多套 所謂成熟的解決方案,我們到底改用那套?

項目問題

迴歸現實,聚焦到目前業務項目上。一個三年左右的項目了,技術棧是非常常規的React框架搭建,初期是使用Redux做的的狀態管理;後來React發佈了Hook特性,看代碼記錄,大家果斷拋棄了Redux,擁抱Hook,項目從某個節點開始,成了清一色的Function式。

好了,現在隨便找個項目開發者諮詢一下,項目存在什麼技術問題,開發體驗如何?瞬間就能開啓吐槽模式:

  • 狀態 凌亂 ,沒有 領域狀態 UI狀態區分
  • 全局狀態 和 局部狀態 設計不合理
  • 數據流邏輯處理 耦合 UI視圖 (CodeReview難,bug不好追蹤,單元測試困難)
  • props drilling 而且傳遞過程 命名多變
  • props 傳遞粒度 不夠精細 (渲染頻率增加)
  • hook使用方式 近乎demo方式,極其不合理,無抽離,無封裝
  • Redux 樣板代碼較多;使用繁瑣;
  • 性能產生了問題,頻繁渲染,無法追蹤什麼操作 導致變更
  • 開發方式 對人的要求較高,心智負擔較高
  • 看起來做了一系列性能優化,還不如vue不優化
  • ......不一一列舉了

那有解決方案嗎?有,大家拉個會議一討論,指定編碼開發規範,嚴格CodeReview,該優化的優化。
OK,問題解決了嗎?沒有,一段時間過後,代碼風格統一了,可是這個真的不重要,問題還是那些問題,舊的代碼能不動就不動,新代碼就直接往上堆砌。

代碼風格統一了,eslint跑過了,可是相比系統架構而言,這些流於形式的東西權重就很低了,重要性微乎其微。

如果不做演化改進,熵增繼續,系統勢必走向崩潰。

這個時候,我們必須思考,出現問題的本質原因到底是什麼?
是歷史遺留問題嗎,是技術棧問題嗎?
都不是,思前想後,還是人的問題,開發者自身的問題。

過度的自由必然導致混亂。

React設計理念 和 哲學思考都是很高的,本身是為了解決UI渲染問題;這就像一把神器,境界高的使用者如臂使指,用來所向披靡,事半功倍;境界不及者,就會感覺深陷泥潭,拿不起來揮不動,終被反噬。

屠龍少年終成惡龍!

講一個段子
一個沒什麼開發經驗,設計模式也不懂,框架立意也不清晰,讀了幾個api用來寫項目的人,怎麼能掌控好呢?
React可能連開發多年的老鳥都不一定能玩明白,上手難度高也不是空穴來風啊,大家可能只是習慣無腦的知道大家這麼説,哦,那就上手難度高。
可是為什麼上手難度高,到底難點在哪裏?照着api開發,難嗎,一點也不對吧

Vue技術棧為什麼就沒有這些問題?為什麼很少出現性能問題?
尤雨溪尤大 設計框架的時候,面向的使用羣體是那些人?框架裏幫我們解決了什麼問題?

所以,本質原因是什麼,這裏就很明白了,但是對於”人“,非常難以掌控。

我們不可能招到的開發者都是非常完美合格的,另一方面,人進步是很困難的,成長曲線都是漫長的S曲線。

那到底有麼有一種方案能 降低人的因素,防止人 對系統架構造成侵蝕和破壞呢?下面我們分析一下

各種解決方案

vue全家桶

vue的響應式設計模式,粒度非常精細,而且 依賴收集 和 依賴派發 邏輯全都有框架自動完成。開發者專注於業務邏輯即可,什麼時候渲染,渲染頻率控制 框架都幫我們處理好了。
單文件模式,把js ,css,html集合在一起的組織方式,本身也是一種功能解耦.

vuex專門為vue框架設計的狀態管理庫,無縫接入。

整體來説,開發體驗還是非常好的,受眾羣體非常龐大,尤其對於初中級開發者來説,根本沒有心智負擔。

既然框架為我們考慮了大部分功能,隨着失去的就是 自定義的靈活性和擴展性,這可能是制約頂級大佬們發揮自我的一個制約點,但是我們不能人云亦云,做拿來主義。對於絕大多數開發者來講,還遠遠達不到觸發這個制約點的高度。

關於vue技術棧相關的講解,這裏就不展開説明了,網上有一大堆分析資料。

react (hook) + redux

React本身只是一個 構建用户界面的javascript庫,官方也是這麼説明的。它的核心兩點是 虛擬dom以及非常高效的diff算法,這才是它的底層競爭優勢。Vue後期的迭代優化也有相關參考,比如引入了虛擬dom機制。

初期全局狀態管理,官方推出了Redux,純函數式編程,功能擴展通過中間件模式。
正如大家煩躁的一點,使用redux,需要大量的模板代碼,使用非常繁瑣;還引入了其他各種概念,比如connect高階組件,容器組件等概念;總之就是使用繁瑣,樣板代碼龐大。

正是上述缺點,所以Hook推出之後,大家彈冠相慶,馬上拋棄redux模式。然後hook依然需要很高的理解成本,甚至比Redux要求更高。但是大家可能不假思索的照着api就開始開發了,導致清一色的Function產生,內部堆積了大量的state,effect,函數體急劇膨脹。hook的狀態設計分層 更是亂七八糟。props傳遞混亂。

講道理,Redux 和 Hook本身都是很好的,大家説起來可能覺得自己都懂,然而落到實處,生產出來的代碼卻遠遠不夠水準。説到底,還是沒懂相關技術的核心設計理念,以及想要解決的問題,思維高度不足導致濫用。

那有沒有想使用 React來構建UI,又想擁有vue的開發體驗呢?答案是肯定的,那就是React + mobx

react + mobx

核心理念:迴歸初心,各自解決各自的問題,React專注於構建用户界面UI,mobx專注於數據邏輯管理,塵歸塵,土歸土。

使用方式請參考

咋一看,react + mobx不就是 繁瑣版的vue嗎?沒毛病,看起來確實是這樣,但又不止於此。

我們用mobx來設計 數據Store以及衍生數據和副作用action的變更,用React構建用户界面。最明顯的一點就是 mobx接管了 React組件的渲染邏輯,把開發者從 渲染的問題上 解放了出來,降低了心智負擔。

數據邏輯內斂到 mobx裏,自然實現了 數據狀態邏輯 和 UI的解耦;也方便各自進行單元測試。

mobx不同於Redux,而是可以多Store實例存在,非常靈活,同時也解決了 數據props傳遞和 組件通信的問題。

在這種模式下開發,那怕一個沒有經驗的開發者隨便開發,也不會對系統的架構造成侵蝕和破壞。

最佳實踐

到了這裏,差不多該有個結論了。

還是那句話,沒有銀彈,也沒有屠龍刀,沒有放之四海而皆準的解決方案。

如果你是個新手開發者,各種設計模式和框架理念理解不是很透徹,又想快速構建應用,那麼vue全家桶可能很適合你上手。

如果你開發經驗非常豐富,做很多底層抽象封裝的工作,需要高度複用定製一些能力,需要專業,那麼React技術棧可能比較適合你,因為你很強。

如果你喜歡使用React,然而又想擁有Vue的開發體驗,那麼React + mobx將非常適合你,你值得擁有。

總結

這篇碎碎念寫的比較多,深度也欠缺,尤其後面很多技術細節,直接沒有;不過無所謂了,這篇也不是講解技術使用的,就是吐吐槽,產生一些想法。

有關技術深度使用的話題,後續有時間再聊!

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.