用Typescript编写自定义React钩子和用普通的JavaScript编写钩子并没有什么不同。在这篇文章中,我们将回顾用Typescript编写自己的React钩子的一些基础知识和 "问题"。
例子 一个简单的useFetch钩子
为了演示如何编写我们的钩子,我们将编写一个钩子,做一些网络应用中非常普遍的事情:获取数据。我们的钩子将被称为useFetch 。
重要的是,我们在这里只是进行基础的学习,所以这将是一个非常原始的钩子。如果你想在生产中真正使用useFetch 钩子,我建议你在谷歌上搜索一个现有的钩子,它有更多的功能和口哨。
发出GET请求
要用我们的钩子发出一个获取请求,我们知道我们需要一个URL,并且我们需要返回一些获取的数据。因此,我们的useFetch 钩子,将有一个url 参数,这个参数是一个string ,并将使用useState 钩子内置的反应存储我们获取的数据。
import { useState } from 'react';
function useFetch(url: string) {
const [data, setData] = useState(null);
// Fetch the data here
return data;
}
现在是有趣的部分:让我们来获取和设置我们的数据吧我们可以简单地使用我们窗口的fetch 方法和setData 到响应。
import { useState } from 'react';
function useFetch(url: string) {
const [data, setData] = useState(null);
// Fetch the data here
fetch(url)
.then((res) => {
return res.json();
})
.then((res) => {
setData(res);
});
return data;
}
让我们通过在一个应用程序中使用我们的钩子来看看这个动作。
import { useFetch } from './useFetch';
function App() {
const data = useFetch('https://api.github.com/users/nas5w');
return data ? <>{JSON.stringify(data)}</> : <>Loading...</>;
}
export default App;
这就成功了。在我们的获取过程中,我们会看到一个Loading... ,然后我们的字符串化的github数据会显示。
但这还不够好:我们的应用程序认为data 的类型是null ,因为那是我们在钩子中明确给我们的有状态的data 变量的唯一类型。
不够好!我们需要键入返回值
为了让自己能够从我们的useFetch 钩子中键入返回值,我们可以使用Typescript泛型来给我们的钩子传递一个类型。让我们看看这将是什么样子。
import { useState } from 'react';
function useFetch<D>(url: string) {
const [data, setData] = useState<D | null>(null);
// Fetch the data here
fetch(url)
.then((res) => {
return res.json();
})
.then((res) => {
setData(res);
});
return data;
}
所以现在我们已经告诉我们的钩子必须提供一个类型,D ,而data 的类型将是D 或null 。我们现在可以重新审视我们的App.tsx 文件并调整我们如何使用这个钩子。
在这个练习中,我已经创建了一个基本的GithubResponse 类型。它可能不是100%正确的,但对于这个演示来说已经足够好了
import { useFetch } from './useFetch';
function App() {
const data = useFetch<GithubResponse>('https://api.github.com/users/nas5w');
return data ? (
<>
Name: {data.login}
<br />
Followers: {data.followers}
</>
) : (
<>Loading...</>
);
}
export default App;
type GithubResponse = {
login: string;
id: number;
node_id: string;
avatar_url: string;
gravatar_id: string;
url: string;
html_url: string;
followers_url: string;
following_url: string;
gists_url: string;
starred_url: string;
subscriptions_url: string;
organizations_url: string;
repos_url: string;
events_url: string;
received_events_url: string;
type: string;
site_admin: boolean;
name: string;
company: string | null;
blog: string | null;
location: string | null;
email: string | null;
hireable: string | null;
bio: string;
twitter_username: string | null;
public_repos: number;
public_gists: number;
followers: number;
following: number;
created_at: string;
updated_at: string;
};
正如我们所看到的,我们的代码被编译了,这意味着Typescript理解我们返回的对象类型!
TL;DR:泛型使你的钩子发挥作用
TL;DR在这里是,Typescript泛型是让你的React Hooks在Typescript中工作的关键!