Skip to main content

使用 useEffect 來掌管元件作用

2 min read

可以取代 Class Component 的神兵利器之一,無疑是 useState 還有本篇介紹的 useEffect。

useEffect 基本運作的機制

在 Class Component 中,有著生命週期的 API,生命週期代表著一個元件從誕生到結束,在 Vue 也有相似的概念,每個階段有不同的 API 可以操作。

為了測試 useEffect 如何在元件中運作,下方寫了一個範例:

import React, { useState, useEffect } ``` from 'react' export default function App() { console.log('first'); const [msg, setMsg] = useState('default'); useEffect(() => { console.log('useEffect'); }); return ( <> {console.log('render')} <button onClick={() => setMsg('default')}>1</button> <button onClick={() => setMsg('change1')}>2</button> <button onClick={() => setMsg('change2')}>3</button> <h1>{msg}</h1> </> ) } 當每次 render 的時候,看到 console.log 的順序是,而且每點選不同按鈕顯示不同內容也是一樣:

'first'; 'render'; 'useEffect'

也就是不管頁面是第一次編譯或是重新編譯,useEffect 都會執行。 如果想要每當狀態改變時就執行 useEffect 的話,就加上第二個參數,並在陣列內給值,例如: useEffect(() => { console.log('useEffect'); }, [msg]); 如果參數沒有給值的話,則會變成只在首次編譯畫面時才會執行 useEffect。 這是因為參數內的值沒有改變,所以 useEffect 就不會執行;那麼如果在同一個頁面,由於值是一樣的,所以也是不會執行。 其他觸發方式 useEffect 還有其他運用的地方,例如想要在 state 的值改變前做其他事情的話,就可以在 useEffect 的函式中回傳一個函式: useEffect(() => { // do some thing return () => { // do another thing } }, []) 下方做了一個範例: 執行的順序是: ```jsx useEffect(() => { (A) return () => { (B) } },[])
  • 當元件編譯完,會執行 (A)
  • 當元件內的 state 改變而重新渲染的話,會先執行 (B) 再執行 (A)
  • 當元件被移除時,會執行 (B)

適合使用 useEffect 的情境

由於 useEffect 會在編譯完執行的特性,所以也就非常適合拿來使用串接 API 取得資料時使用。

下方是使用 useEffect 來串接 API 的範例,使用的是 政府資料開放平台 中的臺北市空品每小時監測資料,比對出士林區及臭氧的相關資訊:

See the Pen useEffect-demo by Bucky Chu (@bucky0112) on CodePen.