useEffect()
本身是個函式,由 React 框架提供。
什麼時候使用 useEffect()
當元件狀態(useState)或變數變動之後,要做什麼事情可透過useEffect來監聽執行。useEffect()
也是個通用的 Hook,找不到對應的 Hook 使用時也可以使用 useEffect()
。
例如當我們載某個元件載入之後,希望網頁標題隨之變化顯示:「歡迎來這裡」,那麼改變網頁標題這個動作就需要透過 useEffect 來完成。
1 | import React, { useEffect } from "react"; |
useEffect() 做什麼事?
以上述的例子來說,useEffect()
的參數是函式,這個函式要完成的就是改變網頁的標題,元件載入後 React 就會去執行這個參數的函式。元件每渲染一次,此函式就自動執行一次,元件在第一次載入頁面時,這個函式也會執行。
useEffect() 的第二個參數
剛剛說過 useEffect()
的第一個參數是函式,第二個參數何時用呢?
有時候我們並不希望 useEffect() 每次渲染都執行,這時第二參數就派上用場,使用一個 Array 來指定 useEffect()
的依賴項(資料),只有依賴項發生變化,才會重新渲染。
1 | const Welcome=(props)=>{ |
上述例子中,useEffect()
的第二個參數是 Array,指定第一個參數函式的依賴項(props.name)
只有此依賴項的變數產生變化時,第一參數的函式才會執行。
如果第二參數是一個空的 Array,就表示第一個參數函式沒有依賴項,也因此第個參數函式只會在元件載入頁面時執行一次,之後元件重新渲染時就不會執行了。
useEffect() 的用途
useEffect()
常見的用途有:
- 獲取資料/call API (data fetching)
- 事件的監聽或訂閱(setting up a subscription)
- 改變 DOM 元素(changing the DOM)
- 輸出日誌(logging)
使用 useEffect call API
終於寫到重點了,useEffect()
最常用來獲取遠端伺服器上的資料(call API),以下是範例:
此範例使用 axios
套件
1 | import React, {useState, useEffect} from 'react' |
- 以
useState()
來產生一個狀態變數data
來保存取的得的資料; useEffect()
的第一參數函式使用 async 用來取得從遠端伺服器上非同步取得的資料;- 取得資料後再用
setData()
來觸發元件的重新渲染; - 因為取得資料只需要一次,所以
useState()
的第二參數依賴項為空的 Array;
其他 Call API 的寫法
以下範例是以useEffect()
呼叫 API ,並把回傳的圖片 url 顯示到畫面上的三種寫法,都是使用fetch()
fetch()
是XMLHttpRequest 的升級版,用於在 JavaScript 裡發出 HTTP 請求時使用。fetch()
使用Promise,不使用 callback 函式,因此大大簡化了寫法,寫起來更簡潔。
第一種寫法 fetch, async / await
1 | function CallApi() { |
第二種寫法 fetch, async / await + try / catch
1 | React.useEffect(()=>{ |
第二種寫法 fetch, then / catch
1 | React.useEffect(()=>{ |
useEffect() 何時需要回傳值?
useEffect()
是隨著元件載入的時候執行的,那麼在元件卸載時,有時也需要清理這些useEffect()
,useEffect()
可以回傳一個函式,在元件卸載時執行這個函式就可以清除。
如果不需要清除useEffect()
第一參數函式所做的事,就可以不用回傳任何值。
例如,在元件載入時,我們使用useEffect()
在加載時訂閱了一個事件,並希望在元件卸載時取消訂閱,這時就可以用useEffect()
回傳的函式去取消。
1 | useEffect(() => { |
使用 useEffect() 的注意事項
- 一次只做一件事,不要在
useEffect()
裡一次做多件事,例如 TodoList 有讀取、寫入、刪除,這三件事需要寫成三個useEffect()