一回目をスキップするCustom Hooks
はじめに
そろそろReactでhooksが使えるようになって一年が経ちます。主要なライブラリなどはClassコンポーネントからhooksを利用したFunctionalコンポーネントに置き換わっています。
弊社hokanでもhooksを積極的に採用しています。
さてそんな中、ClassコンポーネントにはあったcomponentDidUpdate
に該当するhooksはないという壁にぶつかりました。
初回は何もしないが2回目以降はなにか処理をはさみたいなどがユースケースにあると思います。そんな便利なCustom Hooksを作成したので紹介します。
実装
import {DependencyList, useEffect, useState} from 'react';
export default function useSkip(effect: Function, deps: DependencyList, times: number = 1) {
const [_times, setTimes] = useState(0);
useEffect(() => {
if (_times >= times) {
return effect();
} else {
setTimes(_times + 1);
}
}, deps);
}
解説
hooks名はuseSkip
としました。
引数
基本的な使い方は、useEffect
と変わりません。第一引数にコールバック関数、第二引数にDependencyListを渡します。
第三引数で何回処理を飛ばすかを渡すことができます。多くの場合、1回しかとばす需要がなさそうなのでデフォルトでtimes=1
としておきます。
実行回数の管理
const [_times, setTimes] = useState(0);
この部分で実行回数を管理する状態を保持します。
if (_times >= times) {
return effect();
} else {
setTimes(_times + 1);
}
この部分で引数の回数に到達していない場合は、コールバックを発火させず、実行回数をインクリメントします。
指定の回数に到達した時点でコールバックが発火し始めます。
動作確認
以下のプログラムで動作を確認します。
ボタンを押したときのuseEffect
やuseSkip
で渡しているコールバックが発火するかを観察します。
import React, {useEffect, useState} from 'react';
import useSkip from '@hooks/useSkip';
function App() {
const [num, setNum] = useState(0);
useEffect(() => {
console.debug(`num: ${num}`);
console.debug('fire useEffect');
}, [num]);
useSkip(() => {
console.debug('fire useSkip');
}, [num]);
useSkip(
() => {
console.debug('fire useSkip 5 times skipped');
},
[num],
5
);
return <button onClick={() => setNum(num + 1)}>increment</button>;
}
初回はuseEffect
のみですが、2回目から1つ目のuseSkip
、5回目からは2つ目のuseSkip
が発火しています。
いい感じですね。componentDidMount
に等しい処理もできそうです。
参考