hacca8

useEffectフックについて

useEffectフックについてまとめていきます。
この記事は、何度も検索しているような内容が出てくる度に更新しようと思います。

useEffectの引数について

useEffectは引数を2つ持ちます。 第1引数は副作用として実行したい関数、第2引数は依存する値を指定する配列です。
以下を例に確認します。

const Counter = () => {
  const [count, setCount] = useState(0)

  useEffect(() => {
    console.log(count)
  },[count])

  return (
    <div>
      <p>count: {count}</p>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>up</button>
    </div>
  )
}

上記だと第1引数はconsole.log(count)を実行する関数。
第2引数に[count]が指定されているので、countの値に依存して第1引数を実行します。
つまりcountの値が変更される度に、第1引数の関数を実行します。

第2引数の指定がない場合は、レンダリングの度に実行されます。
空配列[]の場合は、初回のみ実行されます。

非同期処理について

カウントの度にconsoleに非同期でapiを叩いた結果を出力したいとします。
結果は以下の通りです。

const Counter = () => {
  const [count, setCount] = useState(0)

  useEffect(() => {
    (async () => {
      const res = await fetch('https://hoge?fuga')
      const data = await res.json()
      console.log(data)
    })()
  }, [count])

  return (
    <div>
      <p>count: {count}</p>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>up</button>
    </div>
  )
}

非同期処理の部分を関数でラップしています。
これは、useEffectの第1引数の戻り値にクリーンアップ関数を返す必要があるためです。そのままasyncの非同期処理だけを書くとPromise型が返ってしまうのでエラーになってしまいます。

第1引数がasync () => {}だけだとPromiseが返ってしまうのでエラー