简体   繁体   English

SWR,围绕 useSWR 钩子创建一个包装器以显示加载状态

[英]SWR, creating a wrapper around the useSWR hook to show loading state

I am using SWR in a React.js application and I find myself needing to display the loading status of a request.我在 React.js 应用程序中使用SWR ,我发现自己需要显示请求的加载状态。

I created a helper function that extracts the loading status from an SWRResponse similar to what SWR provides in their documentation examples :我创建了一个辅助函数,它从SWRResponse中提取加载状态,类似于 SWR 在其文档示例中提供的内容:

const isLoading = ({ data, error }: SWRResponse<any, any>): boolean => {
    return data === undefined && error === undefined;
}

I would like to create a wrapper hook, that always adds this information in the return value, similar to the following:我想创建一个包装钩子,它总是在返回值中添加这个信息,类似于以下内容:

const useSWRWithLoading: SWRHook = (...args) => {
    const swrResponse = useSWR(...args);
    return { ...swrResponse, isLoading: isLoading(swrResponse) };
};

Since I used the builtin type SWRHook I have no support for the isLoading value.因为我使用了内置类型SWRHook ,所以我不支持isLoading值。

How I tried solving the issue (without any success):我如何尝试解决问题(没有任何成功):

const useSWRWithLoading = (...args: Parameters<SWRHook>): ReturnType<SWRHook> & { isLoading: boolean } => {
    const swrResponse = useSWR(...args);

    return { ...swrResponse, isLoading: isLoading(swrResponse) };
};

or (this is pretty much the same thing as before)或(这与以前几乎相同)

type SWRHookWithLoading = (...args: Parameters<SWRHook>) => ReturnType<SWRHook> & { isLoading: boolean };

const useSWRWithLoading: SWRHookWithLoading = (...args) => {
    const swrResponse = useSWR(...args);

    return { ...swrResponse, isLoading: isLoading(swrResponse) };
};

One thing I noticed is that:我注意到的一件事是:

type Foo = Parameters<SWRHook>; // type Foo = never
type Bar = ReturnType<SWRHook>; // type Bar = SWRResponse<unknown,unknown>

And I don't know how to fix it.而且我不知道如何解决它。

If I try to make the SWRHookWithLoading Type a generic, I get an error that says: Type 'SWRHook' is not generic.如果我尝试将SWRHookWithLoading类型设为泛型,我会收到一条错误消息: Type 'SWRHook' is not generic. . .

type SWRHookWithLoading<Data = any, Error = any> = (...args: Parameters<SWRHook<Data, Error>>) => ReturnType<SWRHook<Data, Error>> & { isLoading: boolean };

This is puzzling for me because the type definition for SWRHook is:这让我很困惑,因为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>;

which looks like a generic for me.这对我来说似乎是通用的。

I recommend creating a hook for each query, which then allows you to return custom values.我建议为每个查询创建一个钩子,然后允许您返回自定义值。 In the example below, the function useUser returns the data property from the useSWR function as user , as well as custom properties isLoading and isError .在下面的示例中,函数useUseruseSWR函数作为user返回data属性,以及自定义属性isLoadingisError isLoading is true when there is no error, but there is also no data. isLoading在没有错误时为真,但也没有数据。 It is false if there is data, an error, or both.如果有数据、错误或两者兼有,则为假。

function useUser (id) {
  const { data, error } = useSWR(`/api/user/${id}`, fetcher)

  return {
    user: data,
    isLoading: !error && !data,
    isError: error
  }
}

Source: SWR Docs资料来源:SWR 文档

This approach also makes it easier to share queries between areas of your codebase.这种方法还可以更轻松地在代码库的各个区域之间共享查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM