iT邦幫忙

2021 iThome 鐵人賽

0
自我挑戰組

Be friend with JavaScript系列 第 36

React Hooks - useEffect

  • useEffect() 讓我們在 function component 內也可以實現 class function 中的生命週期componentDidMount()componentDidUpdate()componentWillUnmount()
  • 專門處理 side effect,包括 Dom 操作、數據請求、螢幕刷新、計時器、設定 subscription ...等。
  • 讓 component 在 render 後做一些事情,React 會記住我們在 useEffect() 裡傳遞的 function,並在 render 後呼叫它。
  • 在任何情況下,只要第一次 render 都會觸發 useEffect()。

用法:

useEffect(() => {
    // effect 

    return () => {
        // Cleanup function
    }
}, [// Updating])

第一個參數為 function,告訴 React 渲染完畢要執行什麼內容,而 useEffect 回傳的是一個清除的函式(類似 class component 的 componentWillUnmount()),在 component 將要被卸載時觸發,若不需要清除,就可以將回傳值省略為空。

需要清除的函式通常為:取消訂閱、取消網路請求、取消計時器等。

第二個參數是更新狀態的地方,如果不需更新,第二個參數可省略。

  • 如果第二個參數是一個 dependacy array,此時 useEffect() 會在渲染的第一次執行之外,也會在第二個參數的值被改變時執行(類似 class component 的 componentDidUpdate())。
useEffect(() => {
    // 要做的事
},[dependacy array])
  • 如果沒有第二個參數,代表監測所有的東西,只要 state 或 props 有發生任何改變就會觸發 useEffect(),state 或 props 的值被更新幾次就執行幾次
useEffect(() => {
    // 要做的事
})
  • 如果第二個參數是空陣列,代表誰也不監測,只會在 component 渲染的第一次執行(類似 class component 的 componentDidMount()
useEffect(() => {
    // 要做的事
},[])
  • 只要重新渲染,就會執行所有 useEffect

例如:

import React,{ useState, useEffect } from 'react'
const HookUseEffect = () => {
    const [count, setCount] = useState(0);
    const [test, setTest] = useState("test");
    
    // 1. 沒有第二個參數,每次都執行
    useEffect(()=>{
        console.log('我每次都會執行');
    })
    
    // 2. 第二個參數是空陣列,只會執行第一次
    useEffect(()=>{
        console.log('我只會執行第一次');
    },[])
    
    // 3. 第二個參數不是空陣列,這個參數的狀態有被改變時就會執行
    useEffect(() => {
        console.log('test 被改變我就執行');
    }, [test])
    
    return (
        <div>
            <h3>Hook UseEffect</h3>
            <p>{count}</p>
            <button onClick={() => { setCount(count + 1) }}>Click</button>
            <br />
            <p>{test}</p>
            <button onClick={() => { setTest(test.toUpperCase())} }>Test</button>
        </div>
    )
}
export default HookUseEffect

執行上面的程式碼後,可以看到在網頁一被打開時,console 就會顯示三個訊息,是因為在第一次渲染時會執行所有的 useEffect。
https://ithelp.ithome.com.tw/upload/images/20211006/201402825Gf9hp8Sor.jpg
點擊 click 時,因為 count 被改變,在 console 可以看到每次點擊 click 時都會觸發第一個 useEffect() 執行,下圖是點擊 click 2 下的結果,useEffect() 被執行兩次。
https://ithelp.ithome.com.tw/upload/images/20211006/20140282ggxzUhpSKp.jpg
接著點擊 test ,在 console 可以看到第三個 useEffect() 被執行,第三個 useEffect 會因為 test 的狀態被改變就執行。
但這時也可以看到第一個 useEffect() 被執行了,是因為第一個 useEffect() 沒有第二個參數,所以只要在 component 中有任何一個狀態被改變都會執行。
https://ithelp.ithome.com.tw/upload/images/20211006/20140282fYMo2VlH3n.jpg


上一篇
React Hooks - useState
下一篇
React Hooks - useRef
系列文
Be friend with JavaScript39

尚未有邦友留言

立即登入留言