【React】APIをカスタムフックで扱いやすくする
こんにちは Gaji-Labo フロントエンドエンジニアの茶木です。
apiとの格闘の日々が続いています。
特にエラーの取り回しは、非同期処理も重なっており、地味に複雑だと思います。
そこで、一度使いやすいパターンを作ってしまおうと思います。
基本形
エラー処理を書かない基本形は api
の非同期処理を useEffect
の中で吸収し、 res
の有無で、ローディングとコンテンツを出し分けするようにします。
const [state, setState] = useState();
useEffect(() => {
(async () => {
const res = await getSomthingApi();
setState(res);
})();
}, []);
if(!res) return <p>ローディング中</p>
const {data} = res;
return <p>コンテンツ:{data.id}/{data.name}</p>
これにエラー処理を書きたいのですが、ここに try
〜 catch
を書くと少々複雑になりそうです。そこで下準備にカスタムフックを useApiLoader と useAsyncCallback
作ります。
useApiLoader
api
のレスポンスを格納するための state
と api
をセットで扱う useApiLoader
です。基本形の1〜7行目をカスタムフックにした形です。
const useApiLoader = (fn, deps) => {
const [state, setState] = useState();
useEffect(() => {
const f = async () => {
const s = await fn();
setState(s);
};
f();
}, deps);
return state;
};
useAsyncCallback
deps
がついて少し便利な useAsyncCallback
です。非同期版の useCallback
のカスタムフックです。
const useAsyncCallback = (callback, deps) =>
useCallback((...args) => {
const f = async () => callback(...args);
return f();
}, deps);
apiをカスタムフックにする
この useAsyncCallback
でラップした api
のカスタムフック、例として useGetSomethingApi
を作ります。
まずエラー処理のないケースで、レスポンスの加工をこの段階で行っています。今回は return res.data
とし、後続の処理で使わない情報を捨てています。
const useGetSomethingApi = (id: string) =>
useAsyncCallback(async (id) => {
const res = await getSomethingApi(id);
return res.data;
}, [id]);
これにエラー処理を加えると以下のようになります。同じくcatch節
で エラー情報を加工しています。
const useGetSomethingApi = (id: string) =>
useAsyncCallback(async () => {
try {
const res = await getSomethingApi(id);
return res.data;
} catch (e) {
return {
error: {
code: e?.response?.data?.code,
message: e?.response?.data?.message,
}
};
}
}, [id]);
使ってみる
カスタムフックにより、ローディング、エラー、正常表示の書きわけができるようになりました。
const getApi = useGetSomethingApi(id);
const data = useApiLoader(getApi, [getApi]);
if(!data) return <p>ローディング中</p>
if( "error" in data ) {
const { error } = data;
alert(`エラー:${error.code}/${error.message}`);
return <></>;
}
return <p>コンテンツ:{data.id}/{data.name}</p>;
レンダリングパートは非同期処理であることを気にせずに記述できます。
しかも、もし id
が変わると getApi
が作り直され getSomethingApi
が再度呼び出されるので react
の振る舞いにも沿っていて安心ですね!
Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています
弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?
もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!
求人応募してみる!