
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

※ 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 } になることが確認できます。