iT邦幫忙

2022 iThome 鐵人賽

DAY 7
2
Modern Web

React Hook 不求人,建立自己的 Hook Libary系列 第 7

[DAY 07] 三個你不能不知道的 Hook 小知識!

  • 分享至 

  • xImage
  •  

Hook 雖然為一般的function,為了確保自己能夠很好掌握程式碼以及狀態的運作方向,有幾個點(小知識)不能不知道:

小知識開始!

小知識一:Hook 名稱都是 use 開頭

像是 useState, useEffect 都有 use 的前綴,之後打造的 custom hook 也要依循這個規則,相信這個已經是講廢話等級了!

小知識二:Hook 只能使用在 functional component 裡面

如題,只能使用在function component裡面,Class不行,隨便的地方都不行

// WRONG! 只能使用在元件裡面
const [state, setState] = useState()
function App() {
  return ...
}
// WRONG! 不能用在一般function,只能使用在元件上
function normalFunction() {
  const [state, setState] = useState()
  return ...
}
//Class component 沒有 hook,無視,我也不知道怎麼掰進去XD
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
// GOOD!
function App() {
  const [state, setState] = useState()
  return ...
}

小知識三:Hook 要宣告在最頂層

最頂層無非就是不能包在if...else, loops...等等

// WRONG! 沒有宣告在最頂層
function normalFunction() {
  if(true) {
    const [state, setState] = useState()
  } else {
    ...
  }
  return ...
}

小知識四:Hook 也可以包在其他的 Hook 裡面

這個一開始就知道了,而且不是說好三個嗎!?

什麼時候該打造 Custom Hook?

  • 當今天抽取出來的邏輯沒有使用到任何 hook 時,就屬於一般的 function
  • 當很多不同的邏輯衝撞在一起時,可以嘗試打包成 Custom Hook 增加閱讀與維護性
  • 當很多不同的元件需要用到同樣的功能時,可以抽取出來重複使用,減少重工
  • 當你的custom hook 開始複雜的時候,可以嘗試抽取一次

Example

把之前的 Example 嘗試抽取一次吧!

DEMO加熱上桌

分解動作一

我們的目標是把計分的功能獨立抽取出來,因此先來看有哪些是要被抽取的

(以這個例子,基本上就是全部的內容,實務上可能會碰到兩三種功能交疊再一起)

export default function Score() {
  //抽取目標
  const [score, setScore] = React.useState(0); 
  
  //抽取目標
  const handleAddScore = () => { 
    setScore(score + 1);
  };
  
  //抽取目標
  const handleSubScore = () => { 
    setScore(score - 1);
  };

  return (
    <div className="panel">
      <p>Player Score: {score}</p>
      <button onClick={handleAddScore}>+1 Add Score</button>
      <button onClick={handleSubScore}>-1 Sub Score</button>
    </div>
  );
}

分解動作二

建立一個名為 useScore 的 fucntion 並 export 出去

export default function useScore() {
   //your code
}

分解動作三

這個情境下,我們可以直接把內容搬移進來:

export default function useScore() {
  const [score, setScore] = React.useState(0); 
  
  const handleAddScore = () => { 
    setScore(score + 1);
  };
  
  const handleSubScore = () => { 
    setScore(score - 1);
  };
  
  return [score, handleAddScore, handleSubScore]
}

你也可以選擇回傳 object,與 array 差別在於,array 在解構上需要按照順序,object 不用,但若要需要重新命名 object 則要另外使用 :,按照情境選擇適當的設計囉!

const { score: playerScore } = useScore()

分解動作四

再把剛剛建立好的useScore引入原本的component:

import useScore from 'hooks'

export default function Score() {
  const [score, handleAddScore, handleSubScore] = useScore()
  
  return (
    <div className="panel">
      <p>Player Score: {score}</p>
      <button onClick={handleAddScore}>+1 Add Score</button>
      <button onClick={handleSubScore}>-1 Sub Score</button>
    </div>
  );
}

這樣一來就完成啦!

接下來呢?

接下來我們就會開始打造custom hook囉!


上一篇
[DAY 06] useRef 與一般的變數有甚麼不同?
下一篇
[DAY 08] 自己的Hook自己做!useToggle 讓你想開就開,想關就關
系列文
React Hook 不求人,建立自己的 Hook Libary30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言