はじめに
コードレビューをしているとこのコードは優しすぎると思うことが多々あります。
現実世界では優しいことは美徳とされますが、コードが優しいと保守性が崩れていきます。
今回は、コードはもっと無責任に書いて欲しいという話をします。
Reactを知っている前提で書きますが、知らない人もなんとなく言っていることはわかるかと思います。
優しいコード
優しいコードとは複数の責務を持ってしまっているコードです。
以下で郵便番号フォームの一機能を作ってみます。
仕様
- 郵便番号の形式に沿っていない場合
- 「正しい郵便番号を入力してください」とメッセージが出力される
- 正式な郵便番号の形式の場合
- APIからデータをフェッチし、住所が出力される
優しいコード
zipcode
を受け取り、適切なメッセージを返すカスタムフックを作ります。
import { useEffect, useState } from 'react';
import { fetchAddress } from './fetch-address';
export const useAddressMessage = (zipcode: string) => {
const [message, setMessage] = useState('');
useEffect(() => {
if (zipcode.length !== 7) {
setMessage('正しい郵便番号を入力してください');
}
(async () => {
const address = await fetchAddress(zipcode);
setMessage(`${address.pref} ${address.city} ${address.town}`);
})();
}, [zipcode]);
return { message };
};
一見、良さそうに見えるのですが、addressを取得してくる処理とエラーメッセージの処理が同居してしまっていることは問題だと思います。
問題になるシーン
1. エラーメッセージの種類が増えた時
現状、zipcode.length !== 7
の時にエラーを出すという処理しか書かれてません。
でも、zipcodeに-
が入っていた時には別のエラーを出してほしいという要望が増えたらどうでしょう?
次、コードを書く人は条件分岐を増やしてしまい、どんどん肥大化していってしまうと思います。
きちんとエラー処理は分けるべきだと思います。
2. フェッチしたaddressを別のものに使いたいと思った時
今は、messageで連結した文字列を返していますが、もしかしたらフェッチした住所を用いて別のAPIを叩きたくなるかもしれません。
そんな時に密結合してしまっていると切り離しの処理が発生してしまいます。
無責任なコードにリファクタしてみる
アドレスをフェッチするカスタムフック
アドレスをフェッチして返すだけのカスタムフックを作りましょう
このカスタムフックの関心事としては、APIを叩く条件になったらAPIを叩き、レスポンス(アドレス)を返すのみです。
import { useEffect, useState } from 'react';
import { fetchAddress } from './fetch-address';
type Address = {
pref: string;
city: string;
town: string;
};
export const useAddressMessage = (zipcode: string) => {
const [address, setAddress] = useState<Address | undefined>(undefined);
useEffect(() => {
if (zipcode.length !== 7) return;
(async () => {
const res = await fetchAddress(zipcode);
setAddress(res);
})();
}, [zipcode]);
return { address };
};
役割が分かれ、シンプルになりましたね。
再利用性も抜群です。
エラーメッセージを生成する関数
実は、エラーメッセージを出す処理はカスタムフックにする必要すらありません。
zipcode自体がstateなので、値が書き変わるたびに再レンダリングされます。
なので、以下のようなシンプルな関数で良いですね。
export const zipcodeErrorMessage = (zipcode: string) => {
if (zipcode.length !== 7) return 'エラーです';
};
処理が増えたとしても見通しが良さそうです。
まとめ
コードの責務をきちんと分ける。というのはできているようで意外とみんなやりがちだったりします。
みんな優しすぎるんですね。
繰り返しますが、現実世界では優しいは美徳ですが、コードの世界に持ち込まないようにお願いします。