可擴(kuò)展React項(xiàng)目的6個(gè)技巧和優(yōu)秀實(shí)踐
當(dāng)開(kāi)始一個(gè)新的React項(xiàng)目時(shí),把你和你的團(tuán)隊(duì)將遵循的一些準(zhǔn)則放在一起,以使代碼具有可擴(kuò)展性,這總是一個(gè)好主意。
在這篇文章中,我將與你分享我使用React多年的一些見(jiàn)解,這些見(jiàn)解將幫助你確定自己的項(xiàng)目準(zhǔn)則。
1. 了解如何在本地和全局狀態(tài)之間組織狀態(tài)
React是一個(gè)基于UI的當(dāng)前狀態(tài)來(lái)管理UI的庫(kù)。作為一個(gè)開(kāi)發(fā)者,你的工作就是組織好組成你的應(yīng)用程序的狀態(tài)的保存位置。一些開(kāi)發(fā)人員更喜歡將每個(gè)數(shù)據(jù)保留在redux store,以跟蹤所有可用狀態(tài)。但你真的需要為了打開(kāi)或關(guān)閉一個(gè)簡(jiǎn)單的下拉菜單而向你的狀態(tài)管理器派遣一個(gè)動(dòng)作嗎?
與其使用Redux來(lái)跟蹤應(yīng)用程序內(nèi)部的每一個(gè)狀態(tài),不如將一些狀態(tài)保留在本地,以避免過(guò)度設(shè)計(jì)你的應(yīng)用程序。
根據(jù)經(jīng)驗(yàn),你可以提出以下問(wèn)題:
- 應(yīng)用程序的其他部分是否關(guān)心此數(shù)據(jù)?
- 你是否需要能夠基于此原始數(shù)據(jù)創(chuàng)建其他派生數(shù)據(jù)?
- 是否使用相同的數(shù)據(jù)來(lái)驅(qū)動(dòng)多個(gè)組件?
- 對(duì)你來(lái)說(shuō),能夠?qū)⑦@個(gè)狀態(tài)恢復(fù)到給定的時(shí)間點(diǎn)有價(jià)值嗎?
- 你是否要緩存數(shù)據(jù)(例如,使用已存在的狀態(tài)而不是重新請(qǐng)求)?
- 你是否想在熱重載UI組件時(shí)保持這些數(shù)據(jù)的一致性(交換時(shí)可能會(huì)丟失其內(nèi)部狀態(tài))?
使用局部狀態(tài)的組件更加獨(dú)立和可預(yù)測(cè)。
2. 學(xué)習(xí)測(cè)試的好處,并從一開(kāi)始就做
編寫(xiě)自動(dòng)化測(cè)試的問(wèn)題是,到了一定程度,不可能不花費(fèi)大量的時(shí)間和資源來(lái)手動(dòng)測(cè)試你的React項(xiàng)目。
當(dāng)開(kāi)始一個(gè)項(xiàng)目時(shí),因?yàn)槟愕拇a庫(kù)相對(duì)較小,所以很容易為跳過(guò)編寫(xiě)測(cè)試代碼找理由。如果你的React應(yīng)用中只有5到10個(gè)組件,那么編寫(xiě)自動(dòng)化確實(shí)感覺(jué)是個(gè)苦差事,沒(méi)有明顯的好處。但是當(dāng)你的組件超過(guò)五十個(gè),而且你有多個(gè)高階組件時(shí),手動(dòng)測(cè)試你的項(xiàng)目可能要花上一整天的時(shí)間,即便如此,也可能會(huì)有bug悄然而至而無(wú)人察覺(jué)。
是的,編寫(xiě)測(cè)試代碼將幫助你使你的代碼更加模塊化,它將幫助你更快地發(fā)現(xiàn)錯(cuò)誤,并防止在生產(chǎn)中崩潰。但是,當(dāng)手動(dòng)測(cè)試不能再驗(yàn)證代碼是否按預(yù)期工作時(shí),自動(dòng)化測(cè)試的最終目的是幫助你擴(kuò)展項(xiàng)目。
但是你不能在不習(xí)慣的時(shí)候突然寫(xiě)測(cè)試代碼,這就是為什么你必須從頭開(kāi)始。如果你不知道從哪里開(kāi)始,那就從集成測(cè)試開(kāi)始吧,因?yàn)闇y(cè)試最重要的部分就是驗(yàn)證你的組件是否能正常工作。
3. 采用工具來(lái)幫助你擴(kuò)展
通常,你不需要在應(yīng)用程序開(kāi)始時(shí)向你的React項(xiàng)目添加許多工具。但既然我們?cè)谟懻搶eact應(yīng)用擴(kuò)展到一個(gè)龐大的代碼庫(kù),我想說(shuō)的是,你需要采用所有好的工具來(lái)幫助你。
- 為了在團(tuán)隊(duì)成員之間提供一致的代碼模式并減少語(yǔ)法錯(cuò)誤,需要使用Prettier和ESLint。強(qiáng)大的實(shí)用程序庫(kù),如React Router、date-fns和response -hook-form都是不錯(cuò)的選擇。
- 添加TypeScript和Redux可能會(huì)被延遲,直到你的應(yīng)用程序容易出現(xiàn)類(lèi)型錯(cuò)誤,并且你的應(yīng)用程序的部分需要反復(fù)使用相同的狀態(tài),你需要使其全局可用。
- 從一開(kāi)始就實(shí)現(xiàn)狀態(tài)管理是不需要的,因?yàn)镽eact本身已經(jīng)想到了管理狀態(tài)的最佳方式。
- Bit (Github)來(lái)管理和分享你的組件作為獨(dú)立的構(gòu)件。這意味著你要孤立地測(cè)試和渲染每個(gè)組件。這將保證以后更容易維護(hù)和重用它。
- 你還可以使用Next.js代替Create React App來(lái)啟動(dòng)你的項(xiàng)目。
這些工具將幫助你維護(hù)一個(gè)龐大的React代碼庫(kù),但要注意,你添加的每一個(gè)工具都會(huì)增加你項(xiàng)目的復(fù)雜程度。在決定采用此工具之前,請(qǐng)先進(jìn)行研究。
4. 很好地組織項(xiàng)目文件
在擴(kuò)展React應(yīng)用方面,我學(xué)到的一個(gè)最好的技巧是,組織好你的項(xiàng)目文件并給它們命名可以加快你的進(jìn)度。一些開(kāi)發(fā)人員傾向于將 index.js 編寫(xiě)為組件目錄中的主文件,如下所示:
這似乎是合理的,因?yàn)楫?dāng)你將組件導(dǎo)入到其他文件中時(shí),該語(yǔ)句將變成以下形式:
- import Button from '../components/Button';
但是請(qǐng)考慮在代碼編輯器中并排打開(kāi)它們時(shí):
老實(shí)說(shuō),所有這些 index.js 會(huì)讓任何人感到困惑。但如果你把那些index.js文件重命名為組件名,你的導(dǎo)入語(yǔ)句就會(huì)顯得有些丑陋。
- import Button from '../components/Button/Button';
我的團(tuán)隊(duì)最終決定,既要有以組件命名的文件,又要有導(dǎo)出組件的 index.js 文件。
我們還把CSS和單元測(cè)試文件放在組件目錄里面。這樣一來(lái),每個(gè)組件目錄都可以成為一個(gè)獨(dú)立的組件。
5. 建立你的UI /邏輯組件庫(kù)
你不應(yīng)該等到你的項(xiàng)目達(dá)到很大的時(shí)候才去建立一個(gè)組件庫(kù),你可以隨時(shí)隨地共享組件。每當(dāng)一個(gè)新的組件被構(gòu)建,使用Bit來(lái)跟蹤它,并將其分享到你團(tuán)隊(duì)在Bit.dev上的組件集合,或者在你自己的服務(wù)器上。
如前所述,(真正的)獨(dú)立組件易于維護(hù),并且在共享和記錄文檔時(shí),也易于重用。
組件庫(kù)不僅適用于UI組件。邏輯也應(yīng)包括在內(nèi)——在React的情況下,作為自定義鉤子(大體上)。
6. 使用hooks將邏輯與組件分離
隨著項(xiàng)目的發(fā)展,你可能會(huì)注意到,你的一些組件的邏輯似乎會(huì)被重復(fù)使用。為了共享組件的邏輯,你需要寫(xiě)一個(gè)自定義的鉤子。
鉤子是簡(jiǎn)單地將某些值返回到其調(diào)用者的函數(shù),這就是為什么你可以實(shí)現(xiàn)相同的模式以在組件之間重用邏輯的原因。
總結(jié)
永遠(yuǎn)記住,大規(guī)模構(gòu)建React應(yīng)用是一項(xiàng)復(fù)雜的任務(wù),需要你考慮消費(fèi)者和開(kāi)發(fā)者的最佳決策。最終,最好的做法是適合你的用戶和你的團(tuán)隊(duì)。