ReactのuseEffectの依存配列に設定しても初回は実行しない方法

ReactのuseEffectは初回に実行される

ReactのuseEffectの依存配列に変数を設定すると「初回レンダリング時」と「変数の値が更新されたとき」に実行されます。

そのため、例えば以下のようにカウンターのcount変数を設定してconsole.logで確認すると、初回レンダリング時に { count: 0 } が表示されて、ボタンをクリックすると { count: 1 } になります。

TSX
import { useState, useEffect } from 'react'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

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

  return (
    <>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
      </div>
    </>
  )
}

export default App
ReactのuseEffectの依存配列に設定しても初回は実行しない方法

※ if (count === 0) returnをuseEffect内に追記すれば表示されませんが、変更に弱いコードになります。

ReactのuseEffectで初回実行だけ避ける方法

ReactのuseEffectで初回実行だけ避けるには、useRefでレンダリング回数をカウントして、初回のカウント時に+1し、2回目以降に実行するようにifで条件分岐します。

process.env.NODE_ENVが「development」だとReact.StrictModeによる開発時の二重レンダリングが発生するため、「renderCount = useRef(isDev ? -1 : 0)」にして初回の2回レンダリングにも対応できるようにします。

TSX
import { useState, useEffect, useRef } from 'react'
import './App.css'

function App() {
  const [count, setCount] = useState(0)
  const isDev = process.env.NODE_ENV === 'development'
  const renderCount = useRef(isDev ? -1 : 0)

  useEffect(() => {
    if (renderCount.current > 0) {
      console.log({ count })
    } else {
      renderCount.current += 1
    }
  }, [count])

  return (
    <>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
      </div>
    </>
  )
}

export default App

上記コードをConsoleで確認すると、初回レンダリング時に { count: 0 } が表示されず、ボタンをクリックすると { count: 1 } になることが確認できます。

ReactのuseEffectで初回実行を避けるサンプル