普段useEffect()を使っていて、「初回だけ処理を走らせたくない」みたいなケースが結構あると思います。
今回はそれを抑制する方法と、custom Hookの作り方を紹介します。
コード
具体的な方法としては、useRefで指定した値が初回レンダリングが終わるまではcurrentに入らないことを利用して実現します。
import React, {useState, useRef, useEffect} from 'react';
export default function App() {
const [click, setClick] = useState(false);
const [clicked, setClicked] = useState(false);
const initialRender = useRef(true);
useEffect(() => {
if(initialRender.current) {
initialRender.current = false;
}else {
setClicked(true);
}
}, [click]);
return (
<div>
{clicked && <div>Button has clicked!</div>}
<button onClick={() => setClick(true)}>
Click
</button>
</div>
)
}
上記のように書くことで、初回レンダリングが終わった直後にはinitialRender.currentにはtrueが入るため依存配列が変化すれば任意の副作用を走らせることができます。
Custom Hook
上記の処理を都度書くのは煩わしいので、Custom Hook化して使いまわせるようにしてしまいましょう。
import {useEffect, EffectCallback, DependencyList, useRef} from 'react';
export const useNonInitialEffect = (effect: EffectCallback, deps?: DependencyList) => {
const initialRender = useRef(true);
useEffect(() => {
let effectReturns: void | (() => void | undefined) = () => {};
if(initialRender.current) {
initialRender.current = false;
}else {
effectReturns = effect();
}
if(effectReturns && typeof effectReturns == 'function') {
return effectReturns;
}
}, deps);
};
通常のuseEffectを使うのと同様の感覚で、上記Custom Hookを用いれば初回レンダリング時の処理を抑制しつつ副作用を持たせることができます。