reactjs - TypeScript 和自定义 React Hook Api 服务
问题描述
我正在尝试创建一个 API 服务来获取我所有组件中的数据。我被打字稿困住了(我不太擅长)
我创建了一个自定义钩子:
使用ApiService.tsx
import React from 'react'
import axios from 'axios'
const useApiService = (url: string) => {
const baseUrl = 'http://localhost:8009'
const [response, setResponse] = React.useState(null)
const [error, setError] = React.useState(null)
React.useEffect(() => {
const fetchData = async (): Promise<void> => {
try {
const res = await axios(`${baseUrl}${url}`)
setResponse(res.data)
} catch (error) {
setError(error)
}
}
fetchData()
}, [url])
return { response, error }
}
export default useApiService
然后在我的组件中使用这个钩子,如下所示:
头文件.tsx
import React from 'react'
import { Button, Form, FormControl, Navbar, NavItem } from 'react-bootstrap'
import Nav from 'react-bootstrap/Nav'
import { Link } from '@reach/router'
import useApiService from '../services/useApiService'
interface NavigationData {
title: string
ID: string
post_excerpt: string
}
interface SiteData {
name: string
}
const Header: React.FC = () => {
const menuQuery: Array<NavigationData> = useApiService('/wp-json/wp-utils/menus')
const siteNameQuery: SiteData = useApiService('/wp-json')
const data = menuQuery.response
const siteName = siteNameQuery.response
if (data && siteName)
return (
<Navbar bg="primary" expand="lg" className="navbar-dark mb-4">
<Link to={'/'}>
<Navbar.Brand>{siteName.name}</Navbar.Brand>
</Link>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
{data.map((item: NavigationData) => (
<NavItem key={item.ID}>
<Link className="nav-link" to={item.post_excerpt}>
{item.title}
</Link>
</NavItem>
))}
</Nav>
<Form className={'my-2 my-lg-0'} inline>
<FormControl type="text" placeholder="Recherche" className="mr-sm-2" />
<Button variant="light" className="my-2 my-sm-0">
Search
</Button>
</Form>
</Navbar.Collapse>
</Navbar>
)
else return null
}
export default Header
但我有打字稿错误Type '{ response: null; error: null; }' is missing the following properties from type 'NavigationData[]': length, pop, push, concat, and 28 more.
我想将数据接口或类型从我的组件注入到我的自定义钩子中,但我不知道这是否是这样做的好方法,以及如何正确地做到这一点。
感谢您的建议
解决方案
因为你像这样初始化状态
// TS will infer type for value of response as null
const [response, setResponse] = React.useState(null)
// TS will infer type for value of error as null
const [error, setError] = React.useState(null)
并{ response, error }
从自定义钩子返回useApiService
,TS 将推断返回类型为{response: null; error: null}
.
如果您想创建useApiService
一个更可重用的钩子,请考虑将其设为泛型,它将采用类型参数 T 并且返回类型将为{ response: T | null; error: Error | null }
. 例如,
function useApiService<T>(url: string): { response: T | null; error: Error | null } {
const baseUrl = 'http://localhost:8009';
const [response, setResponse] = React.useState<T | null>(null);
const [error, setError] = React.useState<Error | null>(null);
React.useEffect(() => {
const fetchData = async (): Promise<void> => {
try {
const res = await axios(`${baseUrl}${url}`);
setResponse(res.data);
} catch (error) {
setError(error);
}
};
fetchData();
}, [url]);
return { response, error };
}
当您使用自定义钩子useApiService
时,现在您只需将您想要的响应类型作为类型参数传递。
interface NavigationData {
title: string
ID: string
post_excerpt: string
}
interface SiteData {
name: string
}
const menuQuery = useApiService<NavigationData[]>('/wp-json/wp-utils/menus')
// Keep in mind that the return type of menuQuery is
// { response: NavigationData[] | null; error: Error | null}
// you can destructure the response and error from the returned value
// const { response, error } = useApiService<NavigationData[]>('/wp-json/wp-utils/menus');
// same applies to siteNameQuery you can either destructure the response and error
// or use siteNameQuery.response and siteNameQuery.error
const siteNameQuery = useApiService<SiteData>('/wp-json')
PS-您需要为与您的 API 的响应相匹配的响应类型创建接口,否则您将丢失类型信息。
推荐阅读
- python - Python 美丽的汤 TypeError:find() 没有关键字参数
- ios - Swift 继承和类
- ractivejs - Ractivejs:如何从动态添加的组件中收集值?
- c# - Ef Core 3.1 和 Identity 框架结合 DB Context
- python-3.x - 在 Python 中为多类分类绘制多个模型的 AUC 分数
- ruby-on-rails - 带有 Rack-Mini-Profiler 的 Rails 环境变量
- android - 带有进度条的倒数计时器不显示进度
- antlr - 否定词法分析器规则/令牌
- python - python中生成器表达式的时间复杂度
- c# - 如何在 asp.net(core)mvc 中读取 json