Hook 雖然為一般的function,為了確保自己能夠很好掌握程式碼以及狀態的運作方向,有幾個點(小知識)不能不知道:
像是 useState, useEffect 都有 use 的前綴,之後打造的 custom hook 也要依循這個規則,相信這個已經是講廢話等級了!
如題,只能使用在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 ...
}
最頂層無非就是不能包在if...else, loops...等等
// WRONG! 沒有宣告在最頂層
function normalFunction() {
if(true) {
const [state, setState] = useState()
} else {
...
}
return ...
}
這個一開始就知道了,而且不是說好三個嗎!?
把之前的 Example 嘗試抽取一次吧!
我們的目標是把計分的功能獨立抽取出來,因此先來看有哪些是要被抽取的
(以這個例子,基本上就是全部的內容,實務上可能會碰到兩三種功能交疊再一起)
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囉!