<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          在工作中對于 Custom React Hooks 一些思考

          共 3022字,需瀏覽 7分鐘

           ·

          2021-11-22 23:24

          當(dāng)我剛接手 React 項(xiàng)目的時候,就對整體項(xiàng)目代碼看了一遍,其中就有一個命名為 customer-hooks,打開一看,全都是命名為 usexxx 的 jsx 文件,后面了解到這是大佬們封裝的自定義 hook。

          于是,今天就自己來總結(jié)一下對于 Custom React Hooks 一些思考。

          自定義 Hook

          以下來自 React 官網(wǎng) 關(guān)于自定義 Hook 的介紹:

          與 React 組件不同的是,自定義 Hook 不需要具有特殊的標(biāo)識。我們可以自由的決定它的參數(shù)是什么,以及它應(yīng)該返回什么(如果需要的話)。換句話說,它就像一個正常的函數(shù)。但是它的名字應(yīng)該始終以 use 開頭,這樣可以一眼看出其符合 Hook 的規(guī)則。

          而對于 Hook 的規(guī)則:

          • 不要在循環(huán),條件或嵌套函數(shù)中調(diào)用 Hook, 確保總是在你的 React 函數(shù)的最頂層以及任何 return 之前調(diào)用他們。
          • 只在 React 函數(shù)中調(diào)用 Hook

          自定義 Hook 封裝了一些邏輯代碼,并能夠把數(shù)據(jù)向下傳遞到渲染樹的操作。

          啟動一個 react 項(xiàng)目

          可以通過如下命令快速創(chuàng)建簡單 react 應(yīng)用,詳細(xì)步驟可以參考官網(wǎng)。

          ?npx?create-react-app?react-demo

          簡單的例子

          下面編寫我們自定義的 Hook,本人還是比較菜雞,所以就拿阿里的 ahooks 官方文檔 學(xué)習(xí)了,在 src 文件目錄下創(chuàng)建如下目錄結(jié)構(gòu),用來存放我們的自定義 hook。

          代碼是來自于 ahooks github 倉庫地址

          PS:這里就不粘貼源碼了,大家可以在上述地址拿到。

          我們的父組件代碼如下:

          import?SubApp?from?'./subApp';
          import?useBoolean?from?'./custom-hooks/useBoolean/index';

          function?App()?{
          ??const?[state,?{?toggle,?setTrue,?setFalse?}]?=?useBoolean(true);
          ??return?(
          ????

          ??????

          Effects:{JSON.stringify(state)}</p>
          ??????


          ?????????toggle()}>
          ??????????Toggle
          ????????button>
          ????????type="button"?onClick={setFalse}?style={{?margin:?'0?16px'?}}>
          ??????????Set?false
          ????????</button>
          ????????
          ??????????Set?true
          ????????button>
          ??????</p>
          ??????>
          ????</div>
          ??)
          }

          export?default?App;

          通過 npm start 啟動項(xiàng)目,可以看到如下界面:

          可以看到,使用了自定義 Hook,我們會省去很多重復(fù)性的邏輯代碼,在父子組件我們都可以使用自定義的 hook。

          思考一

          但是,我就有問題了,雖然自定義 hook 很香,但發(fā)現(xiàn)沒有,當(dāng)我們重新渲染的時候,這一整塊邏輯代碼也會跟著運(yùn)行,如果它的運(yùn)行可以忽略不計(jì)倒還好,但還是要考慮一下萬一情況,比如你運(yùn)行了很多個 hook 呢?

          想了想,既然這個 useBoolean 是依賴于返回的 state,那么是不是可以通過 useMemo 來解決問題。

          查看 ahooks 源碼,果然,就有通過 useMemo 來處理的:

          const?actions?=?useMemo(()?=>?{
          ??const?reverseValueOrigin?=?(reverseValue?===?undefined???!defaultValue?:?reverseValue)?as?D?|?R;

          ??//?切換返回值
          ??const?toggle?=?(value?:?D?|?R)?=>?{
          ????//?強(qiáng)制返回狀態(tài)值,適用于點(diǎn)擊操作
          ????if?(value?!==?undefined)?{
          ??????setState(value);
          ??????return;
          ????}
          ????setState((s)?=>?(s?===?defaultValue???reverseValueOrigin?:?defaultValue));
          ??};
          ??//?設(shè)置默認(rèn)值
          ??const?setLeft?=?()?=>?setState(defaultValue);
          ??//?設(shè)置取反值
          ??const?setRight?=?()?=>?setState(reverseValueOrigin);
          ??return?{
          ????toggle,
          ????setLeft,
          ????setRight,
          ??};
          },?[defaultValue,?reverseValue]);

          思考二

          上述我是有些父子組件,它們都調(diào)用了自定義 Hook ,那么我想的是它們會共享狀態(tài)嘛,畢竟都是返回 state,那么假設(shè)我改了父組件的 state,那么子組件也會跟著變嗎?

          帶著好奇心,我操作了一下界面,將父組件調(diào)用一下 toggle 方法,結(jié)果如下:

          在此基礎(chǔ)上,我再調(diào)用一下父組件的 setTrue 方法試試,結(jié)果如下:

          發(fā)現(xiàn),并不會因?yàn)槎鄠€組件調(diào)用同一個自定義 Hook 而共享狀態(tài)。

          來自 React 官網(wǎng) 的表述:

          自定義 Hook 是一種重用狀態(tài)邏輯的機(jī)制(例如設(shè)置為訂閱并存儲當(dāng)前值),所以每次使用自定義 Hook 時,其中的所有 state 和副作用都是 完全隔離 的。

          那么自定義 Hook 如何獲取獨(dú)立的 state?

          每次調(diào)用 Hook,它都會獲取獨(dú)立的 state。由于我們直接調(diào)用了 useBoolean,從 React 的角度來看,我們的組件只是調(diào)用了 useState 和 useMemo。

          我們可以在一個組件中多次調(diào)用 useState 和 useEffect等,它們是完全獨(dú)立的。

          那么,結(jié)合官方的說法,理解起來就容易多了,其實(shí)我們可以這樣想,每次調(diào)用會返回一個新的實(shí)例,如下述我們使用 useBoolean 代碼:

          const?[state,?{?toggle,?setTrue,?setFalse?}]?=?useBoolean(true);

          其實(shí)可以想象成返回新的實(shí)例,每個實(shí)例都會開一個新的空間存放,那么每個組件引用的那個實(shí)例都是完全獨(dú)立開的,所以就不存在狀態(tài)共享了,放心使用。

          思考三

          既然狀態(tài)隔離了,我在想有啥辦法能夠共享狀態(tài)呢?

          我想有時候也得需要在組件之間共享狀態(tài)的。

          于是,我又翻了翻公司代碼以及問了我導(dǎo)師,我發(fā)現(xiàn)居然使用了 context,那么,就得研究一下 context 的一些用法。

          結(jié)尾

          為了讓文章少點(diǎn)廢話,讓大家在簡單的時間內(nèi)能夠吸收知識,本篇內(nèi)容就先到此了,下一篇我們將講解 React Context 的一些使用方法,來解決上文的思考。

          關(guān)于本文內(nèi)容,也歡迎和大家交流討論。

          我是【一百個Chocolate】,如果喜歡的話,可以給本文【點(diǎn)贊】,我們下期再見啦~

          -?END -

          如下是小獅子春秋招過程中學(xué)習(xí)整理的思維導(dǎo)圖以及 PDF 文檔,會不斷更新,目前已有 9?份思維導(dǎo)圖 + 335 頁筆記文檔,現(xiàn)在分享給大家,在公眾號后臺回復(fù)「小獅子」,關(guān)注領(lǐng)取


          學(xué)如逆水行舟,不進(jìn)則退

          點(diǎn)贊 + 在看,好文不白嫖嗷~


          瀏覽 58
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产激情综合五月久久 | 亲子伦一区二区三区观看方式 | 国产肉体ⅩXXX137大胆 | 欧美性爱亚洲日韩 | 男女尻屄视频 |