react hooks 如何自定義元件(react函式元件的封裝)

Mr.聶發表於2021-12-27

前言

  這裡寫一下如何封裝可複用元件。首先技術棧 react hooks + props-type + jsx封裝純函式元件。類元件和typeScript在這不做討論,大家別白跑一趟。

       接下來會說一下封裝可複用元件的思路,比如一個新手應該怎麼去封裝,都需要有哪些東西。

  然後說一些複雜元件需要的功能,比如閉合標籤內部dom怎麼處理,其實就是插槽功能,比如資料監聽,內部做一些業務邏輯。

  想看原碼的點這裡,這是一個GitHub上完整的 react hooks 專案,  點這裡,看原始碼

 

目錄

1、思路 及 封裝的誤區

2、 props 的型別檢測、預設值

3、父子元件與他的資料互通

4、實現類似於vue插槽一樣的功能 (children屬性)

5、useState、useEffect等hooks講解

6、總結

 

一、思路

  無論是js還是C++等等,都要求 模組內高內聚、模組間低耦合。簡單點說就是你改了一個模組,另一個模組稍作修改就行,不至於改動很大。根據這個程式設計思想,一個可複用的元件的對外互動,就是決定他耦合度的關鍵。把元件比作香腸機,輸入豬肉,輸出香腸。輸入就是props,輸出就是介面效果 以及 給外部反饋的回撥函式。關於輸入props,我們對他有要求,就是型別檢查和預設值。比如輸入的得是豬肉不能是石頭,預設做小香腸,而不是大香腸。回撥函式也有要求,你得儘可能滿足可以預知的邏輯,簡單說就是你以後用這個元件的時候,需要某個資料,這個元件得支援,得有對應的回撥。

  注意,這裡說幾個誤區,也是很多新手經常犯錯的地方。

  1、專案中可複用元件我認為有2種,而不是所有元件都按照一套標準去規範

    第一種 全域性可複用元件,這類元件類似於antd那種ui庫,是提供給開發專案所有人使用的,頻率高。這一類必須嚴格規範,不能亂搞。必須有props的型別檢查,有需要給props加預設值;元件內部只能通過props修改,通過回撥函式反饋,嚴禁其他任何形式的修改;必須對元件功能,props,內部的方法等新增註釋。

    第二種 是一些區域性功能元件,這一類可能只在部分特定情況下會使用,不需要像第一種那種嚴格要求,比較靈活多變,儘可能以簡單通俗易懂去編寫他,比如接下來要描述的幾種禁忌,這類元件並沒有這些要求,只要程式碼精簡、便於維護、易讀。你想怎麼寫都行。就這麼豪橫。

  2、全域性元件

    避免使用redux一類的狀態管理,能用props實現就別懶

    避免使用ref獲取元件資料,能用回撥的都寫上回撥,ref可讀性很差

    保持純淨,自己開發的可以相互引用,但是儘可能避免對第三方、包括UI框架的使用。當然這也不是絕對,二次封裝元件很常見,只是有條件的儘量自己開發。

二、 props 的型別檢測、預設值

  我們使用prop-types做props型別檢查,得安裝一下

  npm i prop-types

  看下面的程式碼,首先引入 prop-types ,然後建立我們的函式元件,這裡有奇點需要注意的,首先,先定義元件,然後在元件原型上做繫結型別檢查;其次因為函式元件,所有用props-types做型別檢查的props,必須在函式元件的形參中顯式的宣告,否則不好使。看程式碼也能理解畢竟繫結在原型上,初始化的時候不宣告,就沒辦法繫結校驗了。所以,我建議一種寫法,所有props都做檢查,都在形參中宣告,能賦預設值的,都寫上預設值,然後在形參的後面把註釋都寫明白了,這樣程式碼一目瞭然,換個人可以很容易接手你的程式碼。這裡囉嗦一嘴,函式元件,本質就是個函式,所以預設值這些都是js函式形參賦預設值的寫法。

  額外囉嗦兩句prop-types的用法,後面這個是他的用法說明:  https://zh-hans.reactjs.org/docs/typechecking-with-proptypes.html

  包括所有的型別、一個props宣告多個型別,物件內部屬性的型別校驗,甚至是定義一個型別檢查的函式

 

 

三、父子元件與他的資料互通

  處理好了props,我們處理回撥,如圖所示,是我寫的一個簡單的回撥,這裡一般不寫預設值,但是要做非空判斷,因為不是所有的屬性,使用者都需要。

 

 

 

 

 四、實現類似於vue插槽一樣的功能 (children屬性)

  封裝元件經常會遇到需要 插槽 的情況,簡單說就是一個閉合元件,內部的dom你想對他做一些處理,比如樣式上的。這裡說一下改怎麼做。看圖,注意一下,如果有一個根標籤,children就是個物件,如果多個並列標籤的話,children就是陣列,用法不一樣,這裡根據需求來,我這裡用的是物件,注意需要定義children的型別,是標籤,還是一個陣列的標籤

 

 

五、useState、useEffect等hooks講解

  最後寫一點函式元件的使用心得。首先父元件變化 或者 函式元件內部變數變化,都會導致函式元件重新執行,如果你在return前面寫個console,會發現執行了很多次,複雜的介面甚至能執行幾十次,這點很操蛋,不過最終diff的時候react會做優化,合併很多變化。而且,函式元件只有hooks,沒有生命週期,這些和類元件差異很大,程式碼邏輯也改變很大。

  1、函式會不斷執行,如果在函式內部宣告變數或者常量會不斷賦值,所以要麼用useState宣告要麼直接放到函式外,比如標記1、3 、4。大家避免寫出死迴圈哈。

  2、useState宣告的變數,預設值智慧賦值一次,比如標記 2

  3、函式元件沒生命週期,useEffect 用於監聽變數變化,可以監聽useState的也可以監聽我們那個標記1這種函式外的。他第二個引數傳空陣列,就只會在元件初始化的時候執行一次,可以在這初始化資料,發http請求,或者時間繫結等。他的觸發機制實在dom渲染結束之後。比如標記 5

  4、useMemo 通過這個hooks可以優化元件的渲染次數,是根據指定變數變化觸發函式執行的

 

u

 

 

 

六、總結

  關於react hooks封裝可複用元件,暫時就想到了這麼多,文章開頭我貼了GitHub的專案地址,因為要說的東西比較多,沒法一個例子就把所有東西清晰、條理的說明白,期間我截圖了好幾個元件的程式碼,大家看原始碼的話,直接看components資料夾。

 

相關文章