P4n*_*1n0 6 javascript fetch typescript swr
我试图弄清楚是否有一种方法可以抽象我为我的 React 应用程序使用 Typescripts 泛型创建的数据获取挂钩。不幸的是,我对 Typescript 的理解并不像我希望的那么好,所以我陷入了困境。
我使用的钩子基于我正在使用的数据获取库 SWR 给出的示例。他们在他们的存储库中有一个我想要构建的示例,但它使用的是 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;
Run Code Online (Sandbox Code Playgroud)
使用的 fetcher 函数是直接从他们的打字稿示例之一复制的,我使用 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,
isLoading: !error && !data,
isError: error,
};
}
export default useProject;
Run Code Online (Sandbox Code Playgroud)
我想要做的是拥有一个钩子(我们将其称为 useRequest,就像 SWR 示例中的那样),我可以获取我需要的大部分数据。对于常规的 Javascript,我可能会这样写:
function useRequest(url, key){
const { data: payload, error } = UseSWR(url, fetcher);
const data = payload[key]
return {
data,
isLoading: !error && !data,
isError: error
};
}
Run Code Online (Sandbox Code Playgroud)
但是,当我想将其用于多种不同的数据类型时,我该如何在 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;
Run Code Online (Sandbox Code Playgroud)
至少它tsc以我期望的形式传递并返回数据。如果有人有更优雅的解决方案,我也很乐意看到。
| 归档时间: |
|
| 查看次数: |
8032 次 |
| 最近记录: |