🐥
【暫定対応】router.queryとuseSWRを組み合わせて使う
課題
- hooksはuseEffectの中で使えない。
- ESLint: React Hook "useTrainingBundlePrograms" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.(react-hooks/rules-of-hooks)
- hooksは条件分岐できない
- ESLint: React Hook "useSWR" is called conditionally. React Hooks must be called in the exact same order in every component render.(react-hooks/rules-of-hooks)
- useRouterを使って取得するqueryは初期値がUndefinedになる
上記の理由から、queryに値がセットされてからのみuseSWRが発火していごいい感じにre-fetchしてくれるようにするための方法を調査中。
暫定対応
Repositoryパターンを採用しているので、レポジトリの中でPromiseリジェクトを返し無駄にリクエストさせないようにする。
SampleRepository.ts
~
getSomething(
id: number
): Promise<AxiosResponse<Something>> {
if (!id) {
return Promise.reject(new RouteParameterRequiredError(["id"]));
}
return Repository.get(fetchRoutes.getSomething(id));
}
~
useSomething.ts
import useSWR from "swr";
import { Something } from "@models/Something";
import {
fetchRoutes,
SomethingRepository,
} from "@repositories/SomethingRepository";
import swrResponseFormatter from "@utils/function/swrResponseFormatter";
import { SwrResponse } from "types/swrResponse";
const somethingRepository = new SomethingRepository();
type Response = SwrResponse & {
something: Something | undefined;
};
const useSomething = (id: number): Response => {
const { data, error } = useSWR(
fetchRoutes.getSomething(id),
() => somethingRepository.getSomething(id)
);
const res = swrResponseFormatter(data, error);
return {
something: data?.data,
...res,
};
};
export default useSomething;
page.tsx
~
const router = useRouter();
const { id } = router.query;
const { something, isLoading, isError, message } = useTrainingBundlePrograms(Number(id));
useEffect(() => {
// console.log(something, isLoading, isError, message);
}, [something]);
~
Discussion