微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 SWR 和 fetch api 的类型安全数据获取钩子?

如何解决使用 SWR 和 fetch api 的类型安全数据获取钩子?

我想知道是否有办法抽象我创建的数据获取钩子,使用 Typescripts 泛型,用于我的 React 应用程序。不幸的是,我对 Typescript 的理解不如我希望的那么好,所以我很困惑。

我使用的钩子基于 SWR 提供的 example,我正在使用的数据获取库。他们在他们的存储库中有我想要构建的 example 内容,但它使用的是 Axios,而我使用的是 fetch(确切地说是 isomorphic-unfetch)。

明确地说,我有 useUsers 钩子可以从我的用户端获取所有用户,如下所示:

import useSWR from 'swr';
import fetcher from '../fetcher';
import { User } from '@prisma/client';

type UserHookData = {
    appUser?: User;
    isLoading: boolean;
    isError: any;
};
type UserPayload = {
    user?: User;
};

function useUsers(): UserHookData {
    const { data,error } = useSWR<UserPayload>('/api/users/',fetcher);
    const userData = data?.user;
    return {
        appUser: userData,isLoading: !error && !data,isError: error,};
}

export default useUsers;

使用的 fetcher 函数是直接从他们的打字稿 examples 之一复制的,我使用 prisma 作为我的 ORM,因此我可以通过它访问类型。 User 类型具有电子邮件和姓名等字段。

我有一个几乎相同的钩子可以从我的项目终点获取单个项目:

import useSWR from 'swr';
import fetcher from '../fetcher';
import { Project } from '@prisma/client';

type ProjectHookData = {
    project: Project;
    isLoading: boolean;
    isError: any;
};

type ProjectPayload = {
    project?: Project;
};

function useProject(id: number): ProjectHookData {
    const { data,error } = useSWR<ProjectPayload>(`/api/project/${id}`,fetcher);
    const project = data?.project;
    return {
        project,};
}

export default useProject;

我想要做的是有一个钩子(在 SWR 示例中我们称之为 useRequest),我可以获取我需要的大部分数据。使用常规的 Javascript,我可能会这样写:

function useRequest(url,key){
    const { data: payload,error } = UseSWR(url,fetcher);
    const data = payload[key]
    return {
         data,isError: error
   };
}

但是当我想将它用于多种不同的数据类型时,我将如何在 Typescript 中做到这一点?我想过可能为此使用泛型,但我不确定这是否是解决此问题的正确方法

解决方法

以下使用泛型的钩子似乎有效:

import useSWR from 'swr';
import fetcher from './fetcher';

interface DataPaylaod<T> {
    [key: string]: T;
}

interface DataResponse<T> {
    data: T;
    isLoading: boolean;
    isError: any;
}

function useRequest<T>(url: string,key: string): DataResponse<T> {
    const { data: payload,error } = useSWR<DataPaylaod<T>>(url,fetcher);
    const data = payload ? payload[key] : undefined;
    return {
        data,isLoading: !data && !error,isError: error,};
}

export default useRequest;

至少它通过 tsc 并以我期望的形式返回数据。如果有人有更优雅的解决方案,我也很乐意看到。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?