👌

【ReactTips】Loanパターンライクに、isLoadingの状態を借りて返す実装

2023/12/17に公開

はじめに

React18系以前で実装しているとDataFetchSuspenseがないのでローディングの状態を管理したいことが多いかと思います。
今回は、ローンパターンを参考にして、Loading状態を高階関数で管理する実装Tipsを紹介します。

※ローンパターンの詳細はこちらが詳しいので、気になる方はご覧ください。

コード

以下のような感じです。
withLoadingReaderはカリー化しており、かつ関数を引数に取る高階関数となってます。

import { useState, useEffect } from "react";

const fetcher = (url: string) => async (): Promise<string> => {
	const response = await fetch(url);
	const body = await response.json();
	return body.name as string;
};

export const useDataFetchLoanLoading = (url: string) => {
	const [isLoading, setLoading] = useState<boolean>(false);
	const [data, setData] = useState<string>();

	const withReader = withLoadingReader(setLoading);

	useEffect(() => {
		(async () => {
			const result = await withReader({ exec: fetcher(url) });
			setData(() => result);
		})();
	}, [url]);

	return { result: data, isLoading };
};
type Props = {
	exec: () => Promise<string>;
};

const withLoadingReader =
	(setState: React.Dispatch<React.SetStateAction<boolean>>) =>
	async ({ exec }: Props) => {
		try {
			setState(() => true);
			return await exec();
		} catch (err) {
			throw new Error(err as string);
		} finally {
			setState(() => false);
		}
	};

さいごに

React17系以前でLoading周りをまとめたいんだけどなぁ、といったお悩みをお持ちの方、あるいは、18系にあげてるけど、なんらかの制約でdataFetchSuspenseを使えない方の参考になれば幸いです。

Discussion