10函數(shù)組件設(shè)計模式如何應對復雜條件渲染場景_第1頁
10函數(shù)組件設(shè)計模式如何應對復雜條件渲染場景_第2頁
10函數(shù)組件設(shè)計模式如何應對復雜條件渲染場景_第3頁
10函數(shù)組件設(shè)計模式如何應對復雜條件渲染場景_第4頁
10函數(shù)組件設(shè)計模式如何應對復雜條件渲染場景_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

下載下載2021-06-1712:49《ReactHooks核心原理與實戰(zhàn)12:49所謂設(shè)計模式,就是針對特定場景,提供一種公認的最佳實踐。在前面的課程中,我們已經(jīng)提到了不少模式,比如保證狀態(tài)的唯一數(shù)據(jù)源,語義化的拆分復雜組件,等等。熟練掌握這些模式,可以讓我們的代碼更加簡潔直觀。一個和Hooks相關(guān),用于解決Hooks另一個則是經(jīng)典的renderpropsUI2HooksHooks,而不能放在條件判斷、循環(huán)等語句中,同時也不能在可能的return語句之后執(zhí)行。換句話說,Hooks必須按順序被執(zhí)行到。這個規(guī)則存在的原因就在于,React需要在函數(shù)組件內(nèi)部維護所用到的Hooks的狀態(tài),所以我們無法在條件語句中使用Hooks,這因而會給我們實現(xiàn)業(yè)務邏輯帶來一定的局限。visiblevisiblevisibletrueimportimport{Modal}from"antd";importuseUserfrom"../09/useUser";functionUserInfoModal({visible,userId,...rest})//當visible為falseif(!visible)return//這一行Hook在可能的returnconst{data,loading,error}=return<Modalvisible={visible}{/*對話框的內(nèi)容nullreturnuseUserHook。所以在你的編輯器配置了ReactHooks的ESLint插件之后,會給出下面的錯誤提示:可以看到,因為Hooks使用規(guī)則的存在,使得有時某些邏輯無法直觀地實現(xiàn)。換句話說,Hooks具體做法就是把條件判斷的結(jié)果放到兩個組件之中,確保真正renderUI的組件收到的所針對剛才我們講的例子,就可以在UserInfoModal外層加一個容器,這樣就能實現(xiàn)條件渲////定義一個容器組件用于封裝真正的UserInfoModalexportdefaultfunctionUserInfoModalWrapper({...rest,//使用rest獲取除了visible5})//如果對話框不顯示,則不renderif(!visible)return//return<UserInfoModalvisible{...rest}10這樣的話,我們就間接實現(xiàn)了按條件去執(zhí)行Hooks的邏輯。在實際的使用場景中,可能判斷條件不止visible一個屬性,而會是一些屬性的組合,來具體決定render什么內(nèi)容。雖然這樣的做法不夠直觀,但其實也能帶來一些好處。比如說,在容器模式中我們其實也可以看到,條件的隔離對象是多個子組件,這就意味著它通常用于一些比較大塊邏輯的隔離。所以對于一些比較細節(jié)的控制,其實還有一種做法,就是把判斷條件放到Hoks中去。比如上節(jié)課的例子,我們需要先發(fā)送請求,獲得文章信息,從而知道作者的ID是什么,這樣才能用useUser這個Hook去獲取用戶數(shù)據(jù)。constconstArticleView=({id})=>const{data:article,loading}=useArticle(id);letuser=null;if(article?.userId)user=//6可以看到,我們需要的article這個對象獲取到之后,才能去用useUser這個Hook再去獲取用戶信息。那么同樣的,既然Hook不能放到條件語句中,那我們應該如何做呢?事實上,上一講的例子已經(jīng)給出了答案,那就是把條件語句自包含在Hook之中。這樣當沒有傳遞userId給useUser這個Hook的時候,副作用里實際上什么也不做,比如:functionfunctionuseUser(id)const[data,setData]=const[loading,setLoading]=useState(false);const[error,setError]=useState(null);useEffect(()=>{//當idif(!id)// 10useEffectID話,這個Hook就可以在組件中無條件使用了??傮w來說,通過這樣一個容器模式,我們把原來需要條件運行的Hoos拆分成子組件,然后通過一個容器組件來進行實際的條件判斷,從而渲染不同的組件,實現(xiàn)按條件渲染的目的。這在一些復雜的場景之下,也能達到拆分復雜度,讓每個組件更加精簡的目的。使用renderpropsUI對于Reactrenderprops。因為它解決了UIClass義,renderpropsrender這個函數(shù)從而render實際的內(nèi)容。ClassrenderpropsHOC(高階組件)的兩把利器,但是實際上,HOC的所有場景幾乎都可以用renderprops不過在如今的函數(shù)組件情況下,Hooks有一個局限,那就是只能用作數(shù)據(jù)邏輯的重用,而一旦涉及UI表現(xiàn)邏輯的重用,就有些力不從心了,而這正是renderprops擅長的地方。所以,即使有了Hooks,我們也要掌握renderprops這個設(shè)計模式的用法。為了方便你理解enerros這個模式,我先給你舉一個數(shù)據(jù)邏輯重用的簡單例子。這個例子仍然是我們熟悉的計數(shù)器。有兩個按鈕,加一和減一,并將當前值顯示在界面上。執(zhí)行的效果如下圖所示:如果不考慮UIcountincrease1decrease:讓數(shù)值減1renderprops的組件自行決定UI如何展現(xiàn)。下面的代碼就是這個計數(shù)器的renderprops的實現(xiàn): setCount(count+ },constdecrement=useCallback(()=>setCount(count- },13

returnchildren({count,increment,decrementrenderUIfunctionfunctionCounterRenderPropsExample(){return({({count,increment,decrement})=>return<buttononClick={decrement}>-<button 15childrentagtag會作為children屬性傳遞給組件。那么在使用的時候,是直接傳遞了一個函數(shù)過去,由實現(xiàn)計數(shù)邏輯的組件去調(diào)用這個函數(shù),并把相關(guān)的三個參數(shù)count,increase和decreaseUI。那么在這種場景下,其實用Hooks是更方便的,在第6講中,我其實已經(jīng)給過這么計數(shù)器的Hooks實現(xiàn)的例子,代碼如下:importimport{useState,useCallback}fromfunctionuseCounter()//定義count這個stateconst[count,setCount]=//實現(xiàn)加1constincrement=useCallback(()=>setCount(count+1),//實現(xiàn)減1constdecrement=useCallback(()=>setCount(count-1),//將業(yè)務邏輯的操作exportreturn{count,increment,decrement很顯然,使用Hooks的方式是更簡潔的。這也是為什么我們經(jīng)常說Hooks能夠替代renderprops這個設(shè)計模式。但是,需要注意的是,Hooks僅能替代純數(shù)據(jù)邏輯的renderpropsUIrenderprops的邏輯,這就是我一再強調(diào)必須要掌握renderprops這種設(shè)計模式的原因。為了解釋這個用法,我給你舉一個例子。比如,我們需要顯示一個列表,如果超過一定數(shù)量,則把多余的部分折疊起來,通過一個彈出框去顯示。下面這張圖可以比較直觀地展示這個需求的實際運行效果:可以看到,這里展示了兩個列表。一個只顯示用戶名,這在一些社交軟件的界面上很常見,只顯示幾個點贊的用戶,多余的用一個數(shù)字來表示,鼠標移上去則跳轉(zhuǎn)或者顯示完整列表。5UIHooks通過renderprops這個設(shè)計模式。renderprops的ListWithMoreimportimport{Popover}fromfunctionListWithMore({renderItem,data=[],max})constelements=data.map((item,index)=>renderItem(item,index,data));constshow=elements.slice(0,max);consthide=return<spanclassName="exp-10-list-with-{hide.length>0&&<Popovercontent={<divstyle={{maxWidth:500<spanclassName="more-items-and{"<spanclassName="more-items-trigger">{hide.length} 112importdatafrom3functionListWithMoreExample()=>return<divclassName="exp-10-list-with-7<h1>User8<divclassName="user-9Likedby:{"renderItem={(user)=>return<spanclassName="user-<br<br<h1>User<divclassName="user-<divclassName="user-list-rowuser-list-row-<spanclassName="user-name-<span>JobrenderItem={(user)=>return<divclassName="user-list-<spanclassName="user-name-43可以看到,代碼里使用了兩個ListWithMore組件,通過renderItem這個屬性,我們可以自主決定該如何渲染每一個列表項,從而把一部分UI邏輯抽象出來,形成一個可復用的邏HooksrenderpropsHooks hooks-course-20vzg。你可以fork后自己動手嘗試。renderprops分享給需要的人,Ta訂閱后你可得20贊9 提建?上一 下一 Free

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論