useState
一般函數組件是沒有內部狀態的,如果需要內部狀態,以前需要改成 class
組件,現在可以使用 useState
,參數為變量的初始值,useState
會返回一個數組,分別是變量值,和改變變量的函數
const LikeButton = () => {
const [ like, setLike ] = useState(0)
return (
<button
onClick={ ()=> { setLike(like + 1) }}
>{ like } like</button>
)
}
useEffect
有的操作需要在生命周期中進行,這樣會造成代碼重復,useEffect
就是用來解決這個問題的。
useEffect 定義
useEffect
第一個參數接收一個函數,函數沒有參數,無返回值或者返回一個函數(destructor),返回的函數也無返回值useEffect 第一個參數
第二個參數是可選的,表示觸發這個 Effect 的變量的數組,只要數組中的變量改變了,就會觸發這個 Effect
const MouseTracker:React.FC = () => {
const [ position, setPosition ] = useState({x: 0, y: 0})
useEffect(() => {
console.log('before addEventListener', position.x)
const onMouseClick = (event: MouseEvent) => {
setPosition({
x: event.clientX,
y: event.clientY
})
}
document.addEventListener("click", onMouseClick)
return () => {
console.log('before removeEventListener', position.x)
document.removeEventListener("click", onMouseClick)
}
})
console.log('before render', position.x)
return <p>x: { position.x }, y: { position.y }</p>
}
可以發現執行的順序是:render -> addEventListener -> render -> removeEventListener -> addEventListener
也就是說每次更新視圖都會重新注冊監聽,并且將上一次的監聽移除,非常頻繁,如果我們只想要首次渲染和移除組件的時候執行這個 Effect,可以傳入第二個參數 []
,表示這個 Effect 不依賴 state / props
,所以只會在首次渲染和移除組件的時候觸發