React組件的解耦技巧分享
前提
每個(gè)程序員的夢想都是實(shí)現(xiàn)財(cái)富自由然后就可以不工作了,但是能實(shí)現(xiàn)的都是少數(shù),但是如果在工作中摸魚賺錢,確實(shí)比較好實(shí)現(xiàn)的事。
那怎么實(shí)現(xiàn)呢?
當(dāng)然是通過寫更少的代碼,來實(shí)現(xiàn)我們的功能需求啦,并且最好的話,是讓所有的代碼都能夠復(fù)用。
你可能會(huì)問那要怎么樣才能實(shí)現(xiàn)代碼的復(fù)用呢?
當(dāng)然是正確地將組件的邏輯與其呈現(xiàn)分離開來。
你肯定會(huì)說:說起來容易做起來難,對(duì)吧?
如何有效地將組件解耦
接下來我們就一起來研究如何有效地將組件解耦,讓我們的代碼變的復(fù)用性極高。
在我們開始之前,讓我們看看“耦合”這一基本概念。
耦合
在計(jì)算機(jī)科學(xué)中,耦合是指兩個(gè)或多個(gè)組件之間的依賴關(guān)系的概念。例如,如果組件A依賴于另一個(gè)組件B,那么就可以說A與B耦合在一起。
耦合是我們提高代碼復(fù)用率的敵人,因?yàn)樗鼤?huì)將需要獨(dú)立修改的組件或部分聯(lián)系在一起,從而增加了代碼維護(hù)的難度。這意味著當(dāng)你需要修改其中一個(gè)部分時(shí),可能會(huì)不得不同時(shí)修改其他部分,這會(huì)導(dǎo)致系統(tǒng)更容易出現(xiàn)錯(cuò)誤和問題。
所以我們必須花時(shí)間去review所有需要進(jìn)行修改相對(duì)應(yīng)的部分,否則可能會(huì)引發(fā)很多我們未知的bug。
如果我們將React組件視為一個(gè)純粹的呈現(xiàn)元素,們可以說它可以與很多東西耦合:
- 決定其行為的業(yè)務(wù)邏輯(hooks、自定義hooks等)。
- 外部服務(wù)(API、數(shù)據(jù)庫等)。
- 另一個(gè)React組件(例如,負(fù)責(zé)管理表單狀態(tài)的組件)。
這種緊密的耦合在修改時(shí)可能會(huì)對(duì)系統(tǒng)的其他部分產(chǎn)生不可預(yù)測的副作用。
讓我們來看下面這個(gè)組件
import { useCustomerHook } from './hooks';
const Customer = () => {
const { name, surname } = useCustomerHook();
return (
<div>
<p>{name}</p>
<p>{surname}</p>
</div>
);
};
乍一看,好像一切都很好,但實(shí)際上,它有一個(gè)問題:這個(gè)組件與useCustomerHook耦合在一起,該hook是從外部服務(wù)獲取客戶數(shù)據(jù)。因此,我們的Customer組件不是一個(gè)“純粹”的組件,因?yàn)樗蕾囉谂c其UI呈現(xiàn)無關(guān)的邏輯。
如果,讓我們想要讓useCustomerHook也在其他的組件中使用。那么我們就要對(duì)其進(jìn)行修改,這會(huì)讓我們修改相當(dāng)多的地方,工作量會(huì)很大,因?yàn)槲覀儽仨毿薷乃惺褂盟⑴c它耦合的組件。
解耦React組件的邏輯
還是剛剛那個(gè)例子。Customer組件與自定義的 useCustomerHook耦合,該hook 應(yīng)用了獲取客戶數(shù)據(jù)的邏輯。
那我們應(yīng)該怎么去解耦這個(gè)組件呢?讓他變成純粹的呈現(xiàn)組件。
import { useCustomerHook } from './hooks';
const Customer = ({name, surname}) => {
return (
<div>
<p>{name}</p>
<p>{surname}</p>
</div>
);
};
const CustomerWrapper = () => {
const { name, surname } = useCustomerHook();
return <Customer name={name} surname={surname} />;
};
export default CustomerWrapper;
我們可以使用了一個(gè)包裝組件來解耦Customer組件的邏輯。這種技巧被稱為容器組件,它允許我們修改組件的UI,而不必?fù)?dān)心“破壞”底層邏輯。
現(xiàn)在,我們的Customer只需要關(guān)注顯示呈現(xiàn)信息。所有必要的變量都作為props傳遞,它就可以輕松嵌套在我們的代碼中的任何位置,而無需擔(dān)憂代碼耦合的問題。
雖然我們已經(jīng)成功解決,但是它仍然存在兩個(gè)問題
- CustomerWrapper組件仍與自定義的hoos耦合。因此,如果我想要對(duì)它進(jìn)行修改的話仍然需要修改包裝組件。
- 我們必須創(chuàng)建額外的組件CustomerWrapper來解耦邏輯,這意味著我們需要寫了更多的代碼了。
那我們可以怎么解決呢?我們可以通過使用Composition來解決這兩個(gè)問題。
Composition
在計(jì)算機(jī)科學(xué)中,Composition是一個(gè)概念,指的是將兩個(gè)或多個(gè)元素組合在一起以創(chuàng)建一個(gè)新元素。例如,如果我們有兩個(gè)函數(shù)f和g,我們可以將它們組合在一起以創(chuàng)建一個(gè)新的函數(shù)h,h是f和g的組合。
const f = (x) => x + 1; const g = (x) => x * 2; const h = (x) => f(g(x));
我們也可以將相同的概念應(yīng)用于自定義hook上。事實(shí)上,我們可以將兩個(gè)或多個(gè)自定義hook組合在一起以創(chuàng)建一個(gè)新的自定義鉤hook。
const useCustomerHook = () => {
const { name, surname } = useCustomer();
const { age } = useCustomerAge();
return { name, surname, age };
};
通過使用Composition,我們可以在不創(chuàng)建包裝組件的情況下解耦React組件的邏輯。為了方便地應(yīng)用組合,我們可以使用了react-hooks-compose庫。
讓我們看看如何在我們的示例中應(yīng)用組合。
import composeHooks from 'react-hooks-compose';
import { useCustomerHook } from './hooks';
const Customer = ({name, surname}) => {
return (
<div>
<p>{name}</p>
<p>{surname}</p>
</div>
);
};
export default composeHooks({useCustomerHook})(Customer);
現(xiàn)在,Customer組件確實(shí)是一個(gè)純粹的呈現(xiàn)組件。它與任何自定義鉤子都沒有耦合在一起,只處理UI邏輯。此外,您無需創(chuàng)建任何額外的組件來解耦邏輯。事實(shí)上,組合使您能夠創(chuàng)建更清晰和可讀性更強(qiáng)的組件。
這種技術(shù)的另一個(gè)優(yōu)點(diǎn)在于它如何簡化對(duì)Customer組件的測試。您不必?fù)?dān)心測試業(yè)務(wù)邏輯;您只需要測試UI邏輯。此外,您還可以單獨(dú)測試自定義鉤子。
最后,讓我們看看如果您決定添加一個(gè)新的自定義鉤子,用于處理Customer組件的某些邏輯,例如處理客戶信息記錄的自定義鉤子。
import composeHooks from 'react-hooks-compose';
import { useCustomerHook, useLoggerHook } from './hooks';
const Customer = ({name, surname, age}) => {
return (
<div>
<p>{name}</p>
<p>{surname}</p>
</div>
);
};
export default composeHooks({
useCustomerHook,
useLoggerHook
})(Customer);
總結(jié)
在這篇文章中,我們探討了如何使用hook composition的方法,讓React組件的邏輯更容易理解,并將其變成了一種更像是專注于展示的組件。這種hook composition的技巧就像一把有力的工具,可以幫助我們提高React組件的結(jié)構(gòu)和可維護(hù)性。
這個(gè)方法的核心思想是將業(yè)務(wù)邏輯和展示層清晰地分隔開,這樣我們的組件就更容易閱讀和測試。這種方式有助于提高代碼的可重用性,并且可以更輕松地?cái)U(kuò)展React應(yīng)用,使程序員可以專注于創(chuàng)建更加清晰和性能更佳的組件。
以上就是React組件的解耦技巧分享的詳細(xì)內(nèi)容,更多關(guān)于React組件解耦的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
淺談React Router關(guān)于history的那些事
這篇文章主要介紹了淺談React Router關(guān)于history的那些事,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
React實(shí)現(xiàn)動(dòng)態(tài)調(diào)用的彈框組件
這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)動(dòng)態(tài)調(diào)用的彈框組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
React經(jīng)典面試題之倒計(jì)時(shí)組件詳解
這些天也都在面試,面試的內(nèi)容也大多千篇一律,無外乎vue、react這些框架的一些原理,和使用方法,但是也遇到些有趣的題目,這篇文章主要給大家介紹了關(guān)于React經(jīng)典面試題之倒計(jì)時(shí)組件的相關(guān)資料,需要的朋友可以參考下2022-03-03
React Native全面屏狀態(tài)欄和底部導(dǎo)航欄適配教程詳細(xì)講解
最近在寫 React Native 項(xiàng)目,調(diào)試應(yīng)用時(shí)發(fā)現(xiàn)頂部狀態(tài)欄和底部全面屏手勢指示條區(qū)域不是透明的,看起來很難受。研究了一下這個(gè)問題,現(xiàn)在總結(jié)一下解決方案,這篇文章主要介紹了React Native全面屏狀態(tài)欄和底部導(dǎo)航欄適配教程2023-01-01
React+EggJs實(shí)現(xiàn)斷點(diǎn)續(xù)傳的示例代碼
這篇文章主要介紹了React+EggJs實(shí)現(xiàn)斷點(diǎn)續(xù)傳的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
React報(bào)錯(cuò)之Parameter event implicitly has a
這篇文章主要為大家介紹了React報(bào)錯(cuò)之Parameter event implicitly has an any type,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Vite+React搭建開發(fā)構(gòu)建環(huán)境實(shí)踐記錄
這篇文章主要介紹了Vite+React搭建開發(fā)構(gòu)建環(huán)境實(shí)踐,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09

