はじめに
React初学者向けです。
2022年のReact開発では、hooksを用いて開発することになるかと思います。
useState
、useEffect
...と色々公式のhooksがあったりしますが、
今回お話しするカスタムフックというのは名の通り自分でカスタムしたhooksということですね。
今回は、カスタムフックを使うとどんなメリットがあるのかについてフォーカスを当てて書きます。
カスタムフックのメリット
いきなり本題といきましょう。
カスタムフックの最大のメリットはhooksのロジックをコンポーネントから切り出せることです。
実際に見た方が早いかと思います。
とてもシンプルなカウンターコンポーネントを作ります。
import React, { useState } from 'react';
export const Counter = () => {
const [count, setCount] = useState(0);
const increment = () => setCount((current) => current + 1);
const decrement = () => setCount((current) => current - 1);
return (
<>
<button onClick={decrement}>-1</button>
<span>{count}</span>
<button onClick={increment}>+1</button>
</>
);
};
これが以下のように変わります。
import { useState } from 'react';
export const useCounter = () => {
const [count, setCount] = useState(0);
const increment = () => setCount((current) => current + 1);
const decrement = () => setCount((current) => current - 1);
return { count, increment, decrement };
};
import React from 'react';
import { useCounter } from './use-counter';
export const Counter = () => {
const { count, decrement, increment } = useCounter();
return (
<>
<button onClick={decrement}>-1</button>
<span>{count}</span>
<button onClick={increment}>+1</button>
</>
);
};
ロジックをコンポーネントから分けることができました。
これだけの差分がメリットを生み出すんです。
以下でもう少し複雑なカウンターアプリを作って確かめてみます。
min, maxのあるカウンターアプリ
import React, { useState } from 'react';
const MIN = 0;
const MAX = 10;
export const Counter = () => {
const [count, setCount] = useState(0);
const increment = () => {
// 1. MAX以上は上げれないように
if (count >= MAX) return;
setCount((current) => current + 1);
};
const decrement = () => {
// 2. MIN以下には下げれないように
if (count <= MIN) return;
setCount((current) => current - 1);
};
return (
<>
{/* 3. MINの時はボタンがdisableになるように */}
<button onClick={decrement} disabled={count === MIN}>
-1
</button>
<span>{count}</span>
{/* 4. MAXの時はボタンがdisableになるように */}
<button onClick={increment} disabled={count === MAX}>
+1
</button>
</>
);
};
どんどん見通しが悪くなっていきますね
これがカスタムフックに分けられていると見通しがかなりよくなるかと思います
import { useState } from 'react';
type Props = {
min: number;
max: number;
};
export const useCounter = ({ min, max }: Props) => {
const [count, setCount] = useState(0);
const increment = () => {
if (count >= max) return;
setCount((current) => current + 1);
};
const decrement = () => {
if (count <= min) return;
setCount((current) => current - 1);
};
return { count, increment, decrement };
};
import React from 'react';
import { useCounter } from './dependencies/use-counter';
const MIN = 0;
const MAX = 10;
export const Counter = () => {
const { count, increment, decrement } = useCounter({ min: MIN, max: MAX });
return (
<>
<button onClick={decrement} disabled={count === MIN}>
-1
</button>
<span>{count}</span>
<button onClick={increment} disabled={count === MAX}>
+1
</button>
</>
);
};
かなりコンポーネントの見通しが良くなったかと思います。
まとめ
今回はカスタムフックを使うとロジックをコンポーネントから切り出すことができるため、見通しが良くなるよという話をしました。
実は、テスタビリティが上がるとか、再利用性が高まるとか他にも色々あったりするのですが、見通しが良くなるというだけでメリットがかなり大きいのでそこにフォーカスを当ててみました。
上記はまたの機会に