gpt4 book ai didi

reactjs - 如何使变量的类型为未知或 'Movie' 分配?

转载 作者:行者123 更新时间:2023-12-04 11:56:25 26 4
gpt4 key购买 nike

我正在开发一个钩子(Hook),我可以在其中传递一个发出 Web 请求的函数,它返回 isLoading , dataerror .

const [isLoading, data, error] = useApi(getMovie, idMovie, someAction);
基本上我有一个接收 3 个参数的钩子(Hook)( useApi ):
  • 解析 Web 请求的函数
  • 这个web请求的参数
  • 最后是对回调的调用。

  • 我像这样使用它:
    const idMovie = { _id: "3" };
    // callback function
    const someAction = (data: unknown) => {
    // do something
    return data;
    };

    const [isLoading, data, error] = useApi(getMovie, idMovie, someAction);
    useApi.tsx
    import { AxiosPromise, AxiosResponse } from 'axios';
    import { useState, useEffect } from 'react';
    const useApi = (
    apiFunction: (params: unknown) => AxiosPromise,
    params = {},
    callback: (data: unknown) => void
    ): [boolean, unknown, null | string] => {
    const [data, setData] = useState(null);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState<null | string>(null);

    useEffect(() => {
    apiFunction(params)
    .then(({ data }: AxiosResponse) => {
    setData(data);
    setIsLoading(false);
    if (callback) {
    callback(data);
    }
    })
    .catch(() => {
    setError('Something went wrong');
    setIsLoading(false);
    });
    }, []); //apiFunction, params, callback]

    return [isLoading, data, error];
    };

    export default useApi;
    getMovie对应一个解决web请求的函数
    import axios from "axios";
    type getMovieParams = { _id: string };
    const BASE_URL = "https://jsonplaceholder.typicode.com/todos/";
    const getMovie = (params: getMovieParams): Promise<unknown> => {
    if (params) {
    const { _id } = params;
    if (_id) {
    const url = `${BASE_URL}/${_id}`;
    return axios.get(url);
    }
    }
    throw new Error("Must provide a query");
    };

    export default getMovie;
    调用此钩子(Hook)的代码如下所示:
    import "./styles.css";
    import useApi from "./useApi";
    import getMovie from "./api";
    interface Movie {
    userId: number;
    id: number;
    title: string;
    completed: boolean;
    }

    export default function App() {
    const idMovie = { _id: "3" };
    // callback function
    const someAction = (data: unknown) => {
    // do something
    return data;
    };

    const [isLoading, data, error] = useApi(getMovie, idMovie, someAction);

    const dataResponse = error ? [] : data; //type Movie
    console.log(dataResponse);
    if (isLoading) {
    return <div>Loading...</div>;
    }

    return (
    <div>
    {error && <div>{error}</div>}
    -- Get Data Movie 1--
    <p>{dataResponse.title}</p>
    </div>
    );
    }
    我在这一行遇到打字错误:
    <p>{dataResponse.title}</p>
    这是因为:
    const dataResponse = error ? [] : data; 
    data类型为 unknown ,这是因为它可以是任何类型的 data ,但我想在这种情况下指定数据类型为 ' Movie ',想法是在另一个组件中重用这个钩子(Hook),并且能够说出当这个钩子(Hook)返回时将获得的数据类型 data .
    这是我的实时代码:
    https://codesandbox.io/s/vigilant-swartz-iozn4
    创建这个问题的原因是请求您的帮助解决用红线标记的 typescript 问题。 (文件 app.tsx)
    enter image description here
    如何解决?谢谢

    最佳答案

    可以使用 generics捕获与传递给函数的参数相关的类型。例如,在您拥有的屏幕截图中,关于 params 的 TS 投诉,我们可以声明一个泛型来捕获 params 类型

    function useApi<Params>(
    apiFunction: (params: Params) => AxiosPromise,
    params: Params,
    callback: (data: unknown) => void
    )
    有了这个,我们的第二个钩子(Hook)参数将被输入为 apiFunction 的任何类型。在其 arg 中要求。
    我们做同样的事情来输入我们返回到回调的数据
    function useApi<Params, Return>(
    apiFunction: (params: Params) => Promise<AxiosResponse<Return>>,
    params: Params,
    callback: (data: Return) => void
    )
    我得到了 apiFunction 的返回类型通过检查 axios.get 的类型称呼 get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;如您所见,最后它返回一个 Promise<AxiosResponse<T>> .我们拦截了 T使用我们的通用类型并将其命名 Return现在我们也可以在钩子(Hook)的返回类型和主体中使用这些类型
    ): [boolean, Return | null, null | string] {
    const [data, setData] = useState<Return | null>(null);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState<null | string>(null);

    useEffect(() => {
    apiFunction(params)
    .then(({ data }) => {
    setData(data);
    setIsLoading(false);
    if (callback) {
    callback(data);
    }
    })
    .catch(() => {
    setError("Something went wrong");
    setIsLoading(false);
    });
    }, []); //apiFunction, params, callback]

    return [isLoading, data, error];
    }
    由于您的电影模型特定于 getMovie 调用,您可以将该界面移到那里并输入 axios.get称呼
    interface Movie {
    userId: number;
    id: number;
    title: string;
    completed: boolean;
    }

    const getMovie = (params: getMovieParams) => {
    if (params) {
    const { _id } = params;
    if (_id) {
    const url = `${BASE_URL}/${_id}`;
    return axios.get<Movie>(url);
    }
    }
    throw new Error("Must provide a query");
    };
    通过所有这些添加,当您使用钩子(Hook)时,您会在代码中观察到一些警告,这将迫使您考虑所有可能的值来实现渲染,我像这样重写了它
      ...
    const [isLoading, dataResponse, error] = useApi(
    getMovie,
    idMovie,
    someAction
    );

    if (isLoading) {
    return <div>Loading...</div>;
    }

    if (error) return <div>error</div>;

    return <div>{dataResponse?.title}</div>;
    ...
    https://codesandbox.io/s/generic-hook-arg-types-s8vtt

    关于reactjs - 如何使变量的类型为未知或 'Movie' 分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69384239/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com