React hooks で setTimeout/setInterval を使う
hooksを使っている関数内では状態が変わるたびにfunctionの中が再実行されるので、少し工夫してやる必要がある
setInterval, setTimeout の登録/破棄
useRef でsetIntervalのIDを管理
useCallbackでcallbackが複数登録されないように
code:app.tsx
function useFoo() {
const countRef = useRef<number | null>(null);
useEffect(() => {
startCount();
return () => stopCount();
}, []);
const startCount = React.useCallback(() => {
if (countRef.current !== null) return;
countRef.current = setTimeout(() => {
// do something
}, 1000);
}, []);
const stopCount = React.useCallback(() => {
if (countRef.current === null) return;
clearInterval(countRef.current);
}, []);
}
stateの更新
setXXX 関数をいつもどおり呼ぶだけで良い
stateの取得
setInterval内の関数で値を参照すると、setTimeoutのコールバック関数を登録したときの変数を参照する
useRef 経由等で取得する必要がある
code:app.tsx
function useFoo() {
const dataRef = useRef<string | null>(data);
dataRef.current = data;
...
const startCount = React.useCallback(() => {
if (countRef.current !== null) return;
countRef.current = setTimeout(() => {
console.log(dataRef.current);
}, 1000);
}, []);
...
}
処理が複雑なので、複数箇所で使う場合useInterval 的な関数を作ってあげるのが良さそう
ref