摘要:同時減少了從數據源到葉子結點的層級,減少了中間層級的數量和不必要的重復渲染。模型這個名字是我自己編的,其實是對上面說的結構的一個分離。當然,像之前所說的地圖,天氣預報,按照邏輯他們也屬于,但是他們也獲取數據,處理數據。
之前翻譯了兩篇關于Container&Presentational Component模型的文章,一篇是基礎的Container和Component的定義,另外一篇是進階版,因為翻譯的太爛,感覺有很多錯誤,所以只放原文鏈接。
在這里我想討論一下我自己對這個模型的一些想法。
注:便于書寫,下面統一把Container&Presentational Components模型翻譯為容器&展示組件模型
注:下面圖片中的components文件夾指的是都是Presentational Components文件夾。
基于容器&展示組件模型的目錄結構 Round 1:剛接觸React和這個模型的時候,我認為項目的結構應該是這樣子的:
Containers下面一個jsx文件就代表一個頁面,負責和后臺交互,負責和Redux進行connect,負責傳遞數據給component。在Router里面放入對應頁面的Container
Components下面每個jsx文件就代表頁面里面所有的渲染的內容,負責渲染,和把從container拿到的數據放到頁面上
頂多把一些基礎的component分離出來,便于以后進行復用
可是才用兩天,就知道這么搞有多么坑了。容器組件模型的目的就是復用性,可讀性,可維護性,然而雖然我們很成功的把后臺交互和頁面展示分離開了,但是看到這么多代碼放在一起,我沒有感覺到任何復用性,可讀性,可維護性,那么多代碼,而且都混合了業務邏輯,你讓我怎么復用,理解,維護?!
痛定思痛,決定改一下,針對之前的問題,面向Component做出修改。基本的想法是這樣子的:盡量拆分component,避免把所有的東西都放到一個文件里面; 拆出可復用的組件,便于組件的復用;拆分邏輯復雜的模塊,增加模塊的可讀性和可維護性;所以關鍵字就是“拆、拆、拆”,拆出大好前程,拆出一片藍天...
所以結構成了這樣...
整個代碼結構復雜很多,不過主要的改變就是把基礎組件分離出來(Sidebar, Form之類),每一個頁面也精細化。我們可以更清晰的看出每個文件負責的功能,同時像Sidebar, Form這些組件都可以被多個不同的父組件調用。
當然,這不是結束,雖然上面的方法解決了我們可讀性,可復用性,可維護性,但是也只針對Component的組件,在container中,依然會有很多的代碼堆積在哪里。
而且還有一個很嚴重的問題,先看一個代碼邏輯結構圖:
我們現在的數據是通過Container來進行管理的,所以如果Images需要圖片數據,那么就需要通過Container->Top->Slide->Images這樣進行數據的傳遞,然而這些圖片數據跟中間的組件沒有任何關系,但是他們還必須把數據傳遞給下一級,就像公交車上,從后門遞公交卡到前門刷一樣,中間的人的心理OS其實是:
當然代碼是沒有情感的,不會覺得厭煩,但是由于中間每一層都需要傳遞數據給下層,一旦某些數據發生改變,就造成了中間層級的重新render,浪費了瀏覽器性能的同時,增大了調試的難度,而且接收數據的組件還要考慮“中間那些牲口們有沒有動我的數據”?!
Round 3:所以,為什么一定要讓頂級的container作為唯一的數據來源呢?
讀了這篇文章就知道,Container是可以包含多個Container和Presentational Component的,所以我們可以適當的提升一些組件成為container。如果老板一個人直接管理很多員工,絕對會亂七八糟的,這個情況下,leader這個角色就應運而生,我們修改一下文件的結構:
現在,代碼的邏輯結構就變成這樣子:
作為老板的index.jsx,現在主要負責:
頁面的基礎配置,比如頁面的title,比如頁面整體內容結構的配置
頁面全局的數據的獲取和修改
作為leader的Top, Content,現在主要負責:
和index.jsx進行溝通,獲取基礎配置和數據
負責整合需要的container和component
獲取和處理自己對應模塊的數據,并傳遞給下一層級
作為presentational component的組件,就負責獲取數據并進行渲染
這么做的好處是,分離了原來頂層container的繁重的任務,使代碼更加清晰。同時減少了從數據源到葉子結點的層級,減少了中間層級的數量和不必要的重復渲染。
當然,或許你會覺得之前舉的那個栗子,只有index.js下面有一層container,或許中間節點還是太多。其實container里面可以包含container,根據需要,可以創建很多container在不同的層級上。
Round 4View-Container-Presentational Component模型?這個名字是我自己編的,其實是對上面說的結構的一個分離。我也看到過有人說Page-Module-Component模型,反正大概思路都是一樣的。
其實和上面的差不多,但是作為一個大老板來說,肯定不能和一堆下級員工混在一起,位置看起來有點混亂不說,"客人"(比如Router)來了,還不容易認。所以,我覺得應該給老板一個包間,讓老板們在自己的包間中,聽候客人的調遣。所以做出一點改動:
Okay,這就是我的最終方案,相比于最早的結構,這個結構更清晰,每個模塊負責的功能也更明確,代碼可讀性、可復用性和可維護性更高。
最后自問自答環節Container和Presentational Component的區別?
Container通常會負責和服務端的溝通,還有一些業務邏輯的處理。他們通常只負責獲取數據,處理數據,處理狀態,但一般不知道如何去展示頁面。
Presentational Component通常不知道數據如何獲取,也不知道這些數據是做什么用的,更不知道怎么去操作這些數據,他們一般只負責頁面的渲染,把領導給的數據放到對應的位置。
當然一切都不是絕對的,容器組件模型只是一個指導思想,并不是一個硬性的規定,你可以按照自己的需要來進行改變。而且我在上面給了兩個一般,也是說明這些不是絕對的。Container當然可以負責頁面的展示,老板雖然大部分負責方向和管理,但誰規定老板就不能寫代碼的?!同樣,Component也可以負責獲取數據,舉個栗子,一個地圖的component,或者一個天氣預報的component,他們可以從固定的地方獲取數據,并把數據渲染出來。
Container可以包含Presentational Component?Presentational Component是否可以包含Container?
Container可以包含Container和Component。
但是Component一般不包含Container,雖然這篇文章的作者最后改口說,Component也可以包含Container,但是個人覺得應該保證component的純凈性,如果包含Container,那么就不再純凈,或許在復用的時候,會出現偏差的情況。
當然像我之前所說,一切都不是硬性規定,或許也只是因為我接觸的少所以沒有想到Presentational component需要包含container的情況,一切都根據自己的需要進行調整。
如何知道什么時候要用container,什么時候要用Presentational component?
一般Presentational component應該是純凈(Pure)的,也就是說父級傳給他的數據不變,那么渲染出來的結果也不應該發生任何變化。所以當一個組件需要業務邏輯處理,業務數據獲取,那么可以考慮使用container。如果不需要這些東西,那么考慮使用Presentational component。當然,像之前所說的地圖,天氣預報,按照邏輯他們也屬于component,但是他們也獲取數據,處理數據。
當不知道該使用container還是Presentational component的時候,那么或許你在這個時候并不需要去決定這個問題。這種情況下,可以直接使用container來寫,當你的container變得越來越復雜,代碼量越來越多,邏輯越來越不清晰的時候,你就可以考慮分離處更多的container和Presentational component來。
如果這篇文章指導的方向有錯誤,里面有很多的問題,該怎么辦?
歡迎指出和討論,一切問題都會認真回答,虛心接受。
如果我也答不出來,那我會當作沒看到...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86590.html
摘要:在線注冊賬號,數據存儲于。年了,還不使用的異步控制體系。過度對數據模型進行裝飾的結果便是高耦合,這跟我初衷是基于在線存儲數據有關。 為什么又是Todo,全世界的初學者都在做todo嗎?可能很多人要問這句話,其實這句話可以等同于: 為什么你做了個云音樂播放器? 為什么你做了個新聞閱讀APP? 為什么你做了個VUE/REACT版本的CNODE? 究其本質,這幾個應用都是data-map...
摘要:對于很多中間組件來說,他們并不需要這些,但是他們還必須傳遞給下一級組件。更傾向于,而更傾向于,當然這并不是絕對的。這是篇文章翻譯自的 這是篇文章翻譯自medium的:Presentational and Container Components 譯者語:這篇文章是緊接著對我上一篇翻譯的擴充,對Container Component模式描述的更加細,解決了我很多開發中的困惑。 Prese...
摘要:在一個應用中,如何通過和端進行交互這個問題曾經困擾了我一段時間,經過學習實踐,有了一點心得體會,寫出來和大家分享一下。組件和一樣,和進行交互,將獲取的通過向下傳遞給組件。不足被設計用來和服務器一起運行,并不能很好的和第三方服務交互。 在一個react應用中,如何通過ajax和server端進行交互這個問題曾經困擾了我一段時間,經過學習實踐,有了一點心得體會,寫出來和大家分享一下。 總的...
摘要:如在中在中,聚合積累的結果是當前的對象。被稱為副作用,在我們的應用中,最常見的就是異步操作。至于為什么我們這么糾結于純函數,如果你想了解更多可以閱讀,或者它的中文譯本函數式編程指南。 DvaJS: React and redux based, lightweight and elm-style framework. https://dvajs.com/ 實例項目源碼:https://g...
摘要:更多相關介紹請看這特點僅僅只是虛擬最大限度減少與的交互類似于使用操作單向數據流很大程度減少了重復代碼的使用組件化可組合一個組件易于和其它組件一起使用,或者嵌套在另一個組件內部。在使用后,就變得很容易維護,而且數據流非常清晰,容易解決遇到的。 歡迎移步我的博客閱讀:《React 入門實踐》 在寫這篇文章之前,我已經接觸 React 有大半年了。在初步學習 React 之后就正式應用到項...
閱讀 1894·2021-11-24 11:16
閱讀 3257·2021-09-10 10:51
閱讀 3180·2021-08-03 14:03
閱讀 1261·2019-08-29 17:03
閱讀 3238·2019-08-29 12:36
閱讀 2219·2019-08-26 14:06
閱讀 493·2019-08-23 16:32
閱讀 2662·2019-08-23 13:42