了解 useEffect React Hook 的用途以及如何使用它!

如果你對 React Hook 還不熟悉,可以先閱讀我的React Hook 簡介

在 React 中,我常常使用的一個 Hook 是 useEffect

import React, { useEffect } from 'react'

useEffect 函數會在元件首次渲染以及每次更新後執行。

React 首先會更新 DOM,然後呼叫傳給 useEffect() 的函數。

舉個例子:

const { useEffect, useState } = React

const CounterWithNameAndSideEffect = () => {
  const [count, setCount] = useState(0)
  const [name, setName] = useState('Flavio')

  useEffect(() => {
    console.log(`Hi ${name} you clicked ${count} times`)
  })

  return (
    <div>
      <p>
        Hi {name} you clicked {count} times
      </p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
      <button onClick={() => setName(name === 'Flavio' ? 'Roger' : 'Flavio')}>
        Change name
      </button>
    </div>
  )
}

提示:如果你是熟悉舊版的 React 開發人員,習慣使用 componentDidMountcomponentWillUnmountcomponentDidUpdate 事件,那麼 useEffect 可以取代它們。

你可以選擇從傳給 useEffect() 的函數中 返回一個函數

useEffect(() => {
  console.log(`Hi ${name} you clicked ${count} times`)
  return () => {
    console.log(`Unmounted`)
  }
})

當元件卸載時,將會執行返回的函數中的代碼。

你可以在這個返回的函數中進行任何需要的「清理」工作。

對於舊版開發人員來說,這類似於 componentWillUnmount

useEffect() 可以被多次調用,這相當有用以劃分不相關的邏輯。

由於 useEffect() 函數在每次更新後都會執行,我們可以通過添加一個陣列作為第二個參數,這個陣列包含要觀察的狀態變數列表,從而告訴 React 哪些狀態變數發生變化時才重新執行副作用。

只有在此陣列中的變數之一更改時,React 才會重新執行副作用。

useEffect(() => {
  console.log(`Hi ${name} you clicked ${count} times`)
}, [name, count])

同樣,你可以通過傳遞一個空陣列的方式告訴 React 只在挂載時執行副作用:

useEffect(() => {
  console.log(`Component mounted`)
}, [])

這是我經常使用的技巧。

Codepen 上的範例:

在 CodePen 上查看 React Hooks example #3 side effects,作者是 Flavio Copes (@flaviocopes)。