我在一个React.js应用程序中使用SWR,我发现自己需要显示一个请求的加载状态。
我创建了一个辅助函数,从SWRResponse
中提取加载状态,类似于SWR在他们的文档示例中提供的:
const isLoading = ({ data, error }: SWRResponse<any, any>): boolean => {
return data === undefined && error === undefined;
}
我想创建一个包装器钩子,它总是在返回值中添加这些信息,类似于以下:
const useSWRWithLoading: SWRHook = (...args) => {
const swrResponse = useSWR(...args);
return { ...swrResponse, isLoading: isLoading(swrResponse) };
};
由于我使用内置类型SWRHook
,所以不支持isLoading
值。
我如何尝试解决这个问题(没有任何成功):
const useSWRWithLoading = (...args: Parameters<SWRHook>): ReturnType<SWRHook> & { isLoading: boolean } => {
const swrResponse = useSWR(...args);
return { ...swrResponse, isLoading: isLoading(swrResponse) };
};
或者
type SWRHookWithLoading = (...args: Parameters<SWRHook>) => ReturnType<SWRHook> & { isLoading: boolean };
const useSWRWithLoading: SWRHookWithLoading = (...args) => {
const swrResponse = useSWR(...args);
return { ...swrResponse, isLoading: isLoading(swrResponse) };
};
我注意到一件事是:
type Foo = Parameters<SWRHook>; // type Foo = never
type Bar = ReturnType<SWRHook>; // type Bar = SWRResponse<unknown,unknown>
我不知道该怎么修理它。
如果我试图使SWRHookWithLoading
类型是通用的,我得到一个错误,说:Type 'SWRHook' is not generic.
.
type SWRHookWithLoading<Data = any, Error = any> = (...args: Parameters<SWRHook<Data, Error>>) => ReturnType<SWRHook<Data, Error>> & { isLoading: boolean };
这让我很困惑,因为SWRHook
的类型定义是:
export declare type SWRHook = <Data = any, Error = any>(...args: readonly [Key] | readonly [Key, Fetcher<Data> | null] | readonly [Key, SWRConfiguration<Data, Error> | undefined] | readonly [Key, Fetcher<Data> | null, SWRConfiguration<Data, Error> | undefined]) => SWRResponse<Data, Error>;
对我来说是通用的
我建议为每个查询创建一个钩子,然后允许您返回自定义值。在下面的示例中,函数useUser
从useSWR
函数返回data
属性作为user
,以及自定义属性isLoading
和isError
。当没有错误,但也没有数据时,isLoading
为true。如果有数据、错误或两者都有,则为false。
function useUser (id) {
const { data, error } = useSWR(`/api/user/${id}`, fetcher)
return {
user: data,
isLoading: !error && !data,
isError: error
}
}
来源:SWR Docs
这种方法还可以更容易地在代码库的各个区域之间共享查询。