前陣子參加React讀書會,挑選的主題是useEffect的迷思,所以這次的學習筆記就會先以useEffect這個hook為主題。
什麼是useEffect?
從字面上來看的話,就是「使用作用」的意思。而這裡的effect(作用),指的是side effect,也就是副作用的意思。所謂的副作用指的是與React無關的其他動作,例如手動更改DOM、使用Web API、向API發送請求獲取資料的這些動作。
useEffect該怎麼使用?
這邊就來直接看一下要怎麼使用UseEffect。
1. import useEffect
使用useEffect時,與使用其他React hooks一樣,必須先import
2. 放入callback function當作參數
在useEffect的放入callback function當作參數,callback function內放入要進行的副作用內容。
3. 控制呼叫useEffect內的第一個函式參數的時間點
首先,useEffect在不做任何調整下,會在Dom渲染完後就呼叫一次callback function,如果還需要依照實際狀況調整呼叫callback function被呼叫的時機點,就會需要把一個陣列當作第二個參數放入,這個陣列就是dependencies array。
(1) 只呼叫一次callback function
如果希望只呼叫一次,不因為state、props有變動而再次被呼叫,可以在useEffect裡面放入空陣列當作第二個參數。
這麼做的話,useEffect裡面的callback function就只會在第一次進入畫面後,DOM被整個渲染完成後呼叫。
(2) 每次指定的state,或props有變動,就呼叫callback function
如果希望特定的state、props有變動時,才再次呼叫callback function,就可以特定的state、props放到第二個參數的陣列裡。
在這個情境下,除了進入第一次畫面,DOM被整個渲染完成後會呼叫一次外,當count這個state有變動時,還會再呼叫。
(3) 不管哪一個state,或props有變動,都會呼叫callback function
如果不放入第二個參數,只要有任何state、props有更新,就會呼叫callback function
在這個情境下,除了進入第一次畫面,DOM被整個渲染完成後會呼叫一次外,不管是count,或是其他跟這個callback funtion內要進行的動作無關的state或props有變動,都會再呼叫callback function。
4. 在離開頁面前執行clear的動作(視情況使用,非必要)
除了控制useEffect呼叫被當作第一個參數的callback function外,若有需要在離開畫面前進行clear的動作,例如clearInterval,這個時候只需要在被當作第一個參數的callback function中回傳一個callback function就可以做得到。
在這個情境下,就可以透過return出的callback function進行clearInterval的動作。
useEffect等於生命週期嗎?
了解完useEffect的使用方式後,可能會有一些熟悉React的Class Component生命週期用法的人,會覺得useEffect好像是Functional Component的生命週期,但真的是這樣嗎?接下來透過實際使用的情境來比較一下。
比較的實際情境 - 手動更改DOM&使用setInerval
在Class Component下的情況(使用生命週期)
如果要在Class Component的實作我們要的情境的話,會需要以下幾個部分:
1. 因為一進入畫面就需要執行手動更改DOM和setInterval這兩個動作,所以會需要在componentDidMount這個生命週期的method分別進行這兩個動作。
2. 為了在count有更新後,再手動更改一次DOM,所以需要再componentDidUpdate這個生命週期再變更一次DOM。
3. 離開元件前還需要clearInterval,所以最後還需要在componentWillUnmount的生命週期進行clearInterval。
=> 以上這幾個部分,都會是以元件的生命週期下去思考並實行。
在Functional Component下的情況(使用hook)
如果是在Functional Component裡的話,要實作我們要比較的情境,就會有點不一樣了:
1. 用useEffect個別進行手動更改DOM和setInerval這兩個動作。
2. 手動更改DOM的部分會需要在count變更時,才更新DOM,所以會在第二個參數的陣列中放入count。
3. setInterval的部分只需要在進入畫面後執行一次即可,所以第二個參數只需要放入空陣列。
4. setInerval需要clearInterval的部分透過return出的callback funtion進行。
=> 以上這幾個部分,會以這個動作與哪些state有關,當那些state有變動時,才需要執行動作的方向下去思考並實行。
補充:成為第一個參數的callback function內return的callback function是什麼?(紅框部分)
這是一個cleanup function,用來進行effect的清除。這個cleanup function的執行時間點如下:
1. 離開元件前,也就是元件unmounted前
2. 元件重新渲染前,也就是元件updated前
透過上面的比較,可以發現使用useEffect這個hook,不再把重點放在整個元件的生命週期,而是放在有沒有跟哪個state有關聯?需不需要在有關的state有變動時,再次進行?所以說useEffect等於生命週期嗎?我自己覺得是不太一樣的東西。如果說它像什麼的話,反而比較像Vue的watch。
完整的程式碼內容可以點擊這裡查看
以上就是前陣子在讀書會分享的內容,就整理到這裡囉!掰餔~
留言列表