- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个钩子(Hook),我可以在其中传递一个发出 Web 请求的函数,它返回 isLoading
, data
和 error
.
const [isLoading, data, error] = useApi(getMovie, idMovie, someAction);
基本上我有一个接收 3 个参数的钩子(Hook)(
useApi
):
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
.
最佳答案
可以使用 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/
我是 Swift 的新手,我正在尝试学习关键字“as!”的概念。我从“The Swift Programming Language 2.1”中看到了下面的代码。 我的问题是,如何将代码'for mov
使用 postman POST 一些要在数据库中创建的 JSON,有一个代码片段供您测试。收到一条错误消息,指出方法“电影”未定义,但从未调用过该方法。 {"movie": { "title
我正在开发一个显示即将上映和正在播放的电影列表的电影管理器应用。 这里的错误是 Movie() 在 android.graphics.Movie 中不公开,不能从外部包访问。 请帮忙。 包 com.e
这是什么意思? "Minimize the Flash movie size by limiting the glyphs embedded in the movie" in sIFR3 to imp
我有一个 Vuex 商店: type Movie = { title: string; id: number; } export default new Vuex.Store({ stat
我在 ViewController 中只使用了 1 个 MPMoviePlayerController。我正在做的是呈现一个 ViewController,其中我有一个 ScrollView ,其中有
我正在开发一个钩子(Hook),我可以在其中传递一个发出 Web 请求的函数,它返回 isLoading , data和 error . const [isLoading, data, error]
Future getData() async { var res = await http.get("https://yts.lt/api/v2/list_movies.json");
我正在寻找一种将一些事件“注入(inject)”到在浏览器上运行的 Flash 影片中的方法。我知道 ActionScript 的 ExternalInterface.addCallback 函数,但
我正在使用 Swipebox:http://brutaldesign.github.io/swipebox/我知道我可以像这样使用滑动框幻灯片打开内容 // Link to click Click t
1.6。推荐电影创建一个函数来计算一组电影评论中有多少个相似的关键字并推荐关键词数量最相似的电影。此任务的解决方案需要使用字典。电影评论和关键字位于名为 film_reviews.txt 的文件中,以
我正在尝试在装有 iOS 4.1 的 iPhone 上播放资源文件夹中的视频文件。 MPMoviePlayerViewController 显示该 View ,但它只会随着事件指示器的旋转而永远显示“
The wind blows like flowers of the time. 风吹着如花般破碎的流年. I pretend I do not care you but still I feel
我目前正在使用 Movie DB API 开发移动应用程序。 我目前已获取数据,但正在对其进行硬编码以从数据库中调出蜘蛛侠。 有人能给我指出正确的方向吗?我在下面附上了我的代码:) $(documen
因此,假设我作为Flash演示的一部分进行了长时间的录音。我是否可以像在Media Player或Windows录音机中一样在演示文稿上放置滚动条和开始/停止/暂停/继续按钮,使我可以滚动以基本上跳到
我有一个网站,advocatedaily.com ,主页上有一个 Youtube 视频,无故停止加载。相反,我得到了一个透明的 Flash 对象。右键单击它会显示“电影未加载...”。 关于 othe
我遵循了 Xtend 教程和电影示例。在本教程的最后,您可以找到这个问题: @Test def void sumOfVotesOfTop2() { val long sum = m
在 Ubuntu 16.10 上,我遵循了以下说明: https://github.com/neo4j-examples/movies-java-spring-data-neo4j-4 但是当我去 h
我有一个N-Triples格式的LinkedMDB本地版本,想查询它。现在,我想使用Jena TDB,它可以存储数据以供以后查询使用。我检查了 documentation for TDB Java A
最简单的解释是,我正在 Android 上制作一个非常小的“互动电影”应用程序。 简而言之,当应用加载时,它会播放一部短片(可能最多几秒钟 @ 12-24fps)。然后我将在屏幕上显示 2 个按钮,根
我是一名优秀的程序员,十分优秀!