react的目的是將前端頁面組件化,用狀態(tài)機(jī)的思維模式去控制組件。組件和組件之間肯定是有關(guān)系得,通過合理得組件設(shè)計(jì),給每一個(gè)組件劃定合適得邊界,可以有效降低當(dāng)我們對(duì)頁面進(jìn)行重構(gòu)時(shí)對(duì)其他組件之間得影響。同時(shí)也可以使我們得代碼更加美觀。
1、高耦合低內(nèi)聚。
高耦合:將功能聯(lián)系緊密得部分放到一個(gè)容器組件內(nèi)對(duì)外暴漏出index.js,目錄結(jié)構(gòu)如下:
├── components │ └── App └── index.js
低內(nèi)聚:當(dāng)這個(gè)組件在調(diào)用頁面直接刪除時(shí),不會(huì)觸發(fā)任何影響;減少無必要的重復(fù)渲染;減小重復(fù)渲染時(shí)影響得范圍。
2、展示組件和容器組件
展示組件 | 容器組件 |
---|---|
關(guān)注事物的展示 | 關(guān)注事物如何工作 |
可能包含展示和容器組件,并且一般會(huì)有DOM標(biāo)簽和css樣式 | 可能包含展示和容器組件,并且不會(huì)有DOM標(biāo)簽和css樣式 |
常常允許通過this.props.children傳遞 | 提供數(shù)據(jù)和行為給容器組件或者展示組件 |
對(duì)第三方?jīng)]有任何依賴,比如store 或者 flux action | 調(diào)用flux action 并且提供他們的回調(diào)給展示組件 |
不要指定數(shù)據(jù)如何加載和變化 | 作為數(shù)據(jù)源,通常采用較高階的組件,而不是自己寫,比如React Redux的connect(), Relay的createContainer(), Flux Utils的Container.create() |
很少有自己的狀態(tài),即使有,也是自己的UI狀態(tài) |
這里重點(diǎn)說下this.props.children。通過this.props.children我們很容易讓我們得組件變的低內(nèi)聚。在實(shí)際開發(fā)中往往會(huì)遇到用純組件寫得展示組件下還有要繼續(xù)跟跟數(shù)據(jù)打交道得容器組件。這里就用this.props.children套上這些容器組件就可以了。然后被套得容器組件可以繼續(xù)按照上面得規(guī)則新建個(gè)文件夾暴漏出index.js這種寫法。
這種寫法得最大好處是你很快就能找到你寫得這個(gè)組件是在哪,是干嘛得,影響了哪。
3、從頂部向下得單向數(shù)據(jù)流
當(dāng)我們得設(shè)計(jì)滿足上面這些條件時(shí),使用從頂部向下的單向數(shù)據(jù)流會(huì)讓我們?cè)谑褂靡恍╊愃朴趓edux這種得狀態(tài)管理工具時(shí),影響的范圍更加可控,再通過shouldComponentUpdate來減少不必要的渲染。(不過這么寫確實(shí)挺麻煩的,但是react從 v16.3開始使用新的生命周期函數(shù)getDerivedStateFromProps來強(qiáng)制開發(fā)者對(duì)這一步進(jìn)行優(yōu)化)
4、受控組件和非受控組件
有許多的web組件可以被用戶的交互發(fā)生改變,比如:<input>,<select>。這些組件可以通過輸入一些內(nèi)容或者設(shè)置元素的value屬性來改變組件的值。但是,因?yàn)镽eact是單向數(shù)據(jù)流綁定的,這些組件可能會(huì)變得失控:
1.一個(gè)維護(hù)它自己state里的value值的<Input>組件無法從外部被修改
2.一個(gè)通過props來設(shè)置value值的<Input>組件只能通過外部控制來更新。
受控組件:
一個(gè)受控的<input>應(yīng)該有一個(gè)value屬性。渲染一個(gè)受控的組件會(huì)展示出value屬性的值。
一個(gè)受控的組件不會(huì)維護(hù)它自己內(nèi)部的狀態(tài),組件的渲染單純的依賴于props。也就是說,如果我們有一個(gè)通過props來設(shè)置value的<input>組件,不管你如何輸入,它都只會(huì)顯示props.value。換句話說,你的組件是只讀的。
在處理一個(gè)受控組件的時(shí)候,應(yīng)該始終傳一個(gè)value屬性進(jìn)去,并且注冊(cè)一個(gè)onChange的回調(diào)函數(shù)讓組件變得可變。
非受控組件:
一個(gè)沒有value屬性的<input>就是一個(gè)非受控組件。通過渲染的元素,任意的用戶輸入都會(huì)被立即反映出來。非受控的<input>只能通過OnChange函數(shù)來向上層通知自己被用戶輸入的更改。
#### 混合組件:
同時(shí)維護(hù)props.value和state.value的值。props.value在展示上擁有更高的優(yōu)先級(jí),state.value代表著組件真正的值。
5、使用高階組件(HOC)
簡單定義:一個(gè)接收react組件作為參數(shù)返回另外一個(gè)組件的函數(shù)。
可以做什么:代碼復(fù)用,代碼模塊化增刪改props
使用案例:比方說公司突然要給前端代碼不同的點(diǎn)擊埋點(diǎn),就可以使用hoc包一層,再不改動(dòng)原來各處代碼得同時(shí)進(jìn)行了合理得改動(dòng)。
6、增刪改查標(biāo)準(zhǔn)流程
增:填寫數(shù)據(jù),驗(yàn)證數(shù)據(jù),插入數(shù)據(jù),重新查詢數(shù)據(jù)列表。
刪:確認(rèn)刪除,重新查詢數(shù)據(jù)列表。
查:查詢數(shù)據(jù)列表,分頁顯示
改:填寫數(shù)據(jù),驗(yàn)證數(shù)據(jù),修改數(shù)據(jù),重新查詢數(shù)據(jù)列表
其實(shí)設(shè)計(jì)組件時(shí)沒必要過早的組件化。我們可以先快速的寫出一個(gè)版本,然后再根據(jù)實(shí)際設(shè)計(jì)拆分以應(yīng)對(duì)項(xiàng)目初期的需求快速變更。然后一點(diǎn)一點(diǎn)的按照設(shè)計(jì)模式去改變我們的項(xiàng)目,只要設(shè)計(jì)模式合理拆分其實(shí)是一個(gè)很流暢和自然的事情。