React Hook - CustomHook 建立屬於自己的 Hook - 筆記長也NotesHazuya

React Hook - CustomHook 建立屬於自己的 Hook

2021-07-24 12:17:00   ReactJS

Custom Hook

前面介紹了幾種不同的 Hook,現在我們將要來建立屬於自己的客製化 hook 了!

其實客製化的 hook 就是一個 function,和前面提到的幾種 hook 一樣,只是在客製化 hook 裡面可以做自己要做的事情,這樣有助於簡化程式碼當中複雜的邏輯,將其模組化到其他檔案當中。

與 component 的差別

差異在於 compoment 最後會回傳 JSX ,而 custom hook 會回傳一些資料。

每一個被呼叫的 custom hook 都是獨立的

custom hook 在不同元件呼叫都會是不同的獨立實體,擁有自己的資料。

可以在 custom hook 使用其他 hook

custom hook 之中也可以使用如前面介紹的 useState、useEffect⋯⋯諸如此類的 hook。

使用限制與其他 hook 相同

Custom Hook 同樣受到 hook 的使用限制,一樣包含前面所提過的三點:

  • 不能在 if-else 結構中宣告
  • 不能在 for-loop 中宣告
  • 不能在 functionalComponent 中宣告的 function 中宣告

建立

custom hook 命名方式基本上遵守前面幾種 hook 的命名方式,以 useXXXX 來命名。今天我們要設計一個計算字數的 hook。

先到專案目錄下建立一個 useTextCounter.js 的檔案,並篩寫以下程式碼:

import { useState, useEffect } from 'react';
const useTextCounter = (text) => {
    const [ textLen, setTextLen ] = useState(0);
    useEffect(
        () => {
          setTextLen(text.length)  
        },[text]
    )
    return textLen;
}
export default useTextCounter;

記得傳入參數

在篩寫函式的時候記得要帶入參數,在這裡我們帶入要被計算字數的文字。

回傳資料

最後函式記得要回傳需要的資料,這裡我們回傳計算的字數。

可以使用其他 hook

記得,可以在 custom hook 當中使用其他現成的 hook。

使用

回到 App.js 當中,我們引入寫好的 useTextCounter.js 並使用

import React, { useState } from 'react';
import useTextCounter from './useTextCounter.js'
const App = (props) => {
  const [text, setText] = useState("");
  const textLen = useTextCounter(text); 
  return (  
    <>
      <input type="text" onChange={(e)=>{setText(e.target.value)}}></input> <hr/>
      <h3>現在字數:{ textLen }</h3>
    </>
  );
};
export default App;

這裡我們建立一個 text 的 state,並將其傳入 useTextCounter 這個 hook,並以 textLen 來接收回傳的字數,執行效果如下:

每個被呼叫的 custom hook 都是獨立的實體

同樣一個 custom hook 在不同元件被呼叫都是不同的實體,我們建立一個新的 TwoComponent.js:

import React, { useState } from 'react';
import useTextCounter from './useTextCounter';
const TwoComponent = () => {
    const [text, setText] = useState("");
    const textLen = useTextCounter(text);
    return (  
      <>
        <input type="text" onChange={(e)=>{setText(e.target.value)}}></input> <hr/>
        <h3>現在字數2:{ textLen }</h3>
      </>
    );
}
export default TwoComponent;

一樣將字串傳給 useTextCounter 計算字數。

再來修改 App.js,引入 TwoComponent :

import React, { useState } from 'react';
import useTextCounter from './useTextCounter'
import TwoComponent from './TwoComponent'
const App = (props) => {
  const [text, setText] = useState("");
  const textLen = useTextCounter(text);
  return (  
    <>
      <input type="text" onChange={(e)=>{setText(e.target.value)}}></input> <hr/>
      <h3>現在字數1:{ textLen }</h3>
      <hr/>
      <TwoComponent></TwoComponent>
    </>
  );
};
export default App;

執行結果如下:

會發現兩個元件都呼叫了 useTextCounter,但兩者有不同的數值。

其他

如果 custom hook 利用 [ , ] 回傳多參數,使用時也要利用 [ , ] 的形式來接收,例如上述的 Hook 將 return 改成這樣:

import { useState, useEffect } from 'react';
const useTextCounter = (text) => {
    const [ textLen, setTextLen ] = useState(0);
    useEffect(
        () => {
          setTextLen(text.length)  
        },[text]
    )
    return [text, textLen];
}
export default useTextCounter;

那麼使用時就要改成這樣:

const [text, textLen] = useTextCounter(text); 

結論

Custom Hook 可以讓你把程式變得更模組化,不必重複篩寫同樣的程式碼,也不必為此篩寫成 component 。

React Hook 的部分的此告一段落,我們共介紹了五種不同的 Hook,其中 useState 以及 useEffect 會很頻繁的使用,如果還沒看過可以點以下連結回去看看:

 

 

關於作者


長也

資管菸酒生,嘗試成為網頁全端工程師(laravel / React),技能樹成長中,閒暇之餘就寫一些筆記。 喔對了,也愛追一些劇,例如火神跟遺物整理師,推推。最愛的樂團應該是告五人吧(?)