[英]typescript failed to infer destructuring array type in custom hook
import * as React from "react";
import axios from "axios";
import {Fragment, useState, useEffect} from "react";
interface Ihits {
objectID: string;
url: string;
title: string;
}
interface IinitialData<T> {
hits: Array<T>
}
const useDataApi = (initialUrl:string, initialData: IinitialData<Ihits>) => {
const [data, setData] = useState(initialData);
const [url, setUrl] = useState(initialUrl);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await axios(url);
setData(result.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
fetchData();
}, [url]);
// return [{ data, isLoading, isError }, setUrl];
return [{data, isLoading, isError }, setUrl];
};
const UseDataFetch: React.FC = () => {
const [query, setQuery] = useState('redux');
**const [{data, isLoading, isError}, setUrl] = useDataApi(**
'https://hn.algolia.com/api/v1/search?query=redux',
{ hits: [] },
);
return (
<Fragment>
<form
onSubmit={event => {
**setUrl(**
`http://hn.algolia.com/api/v1/search?query=${query}`,
);
event.preventDefault();
}}
>
<input
type="text"
value={query}
onChange={event => setQuery(event.target.value)}
/>
<button type="submit">Search</button>
</form>
{isError && <div>Something went wrong ...</div>}
{isLoading ? (
<div>Loading ...</div>
) : (
<ul>
{data.hits.map((item: Ihits) => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
)}
</Fragment>
);
}
export default UseDataFetch;
我研究了這個鏈接https://www.robinwieruch.de/react-hooks-fetch-data 的例子
我嘗試了各種解決方法,但根本無法設置類型化解構值。 除了使用任何類型和對象返回(例如:返回 {data, isLoading, isError , setUrl};)
很感謝有人能告訴我我錯過了什么
Typescript 無法推斷它,因為您正在返回每個元素屬於不同類型的數組。 從 Typescript 的角度來看,如果您不明確輸入它,就無法將它們關聯起來。
return [{data, isLoading, isError}, setUrl];
第一種方法是您明確定義useDataApi
方法的返回類型:
const useDataApi = (initialUrl:string, initialData: IinitialData<Ihits>):
[{data: IinitialData; isLoading: boolean; isError: boolean}, string] => {
// your code here
}
其他方法是您返回特定類型的對象而不是數組。 您可以定義自定義類型:
type DataApiResponse = {
response: {
data: IinitialData<Ihits>;
isLoading: boolean;
isError: boolean;
};
setUrl: Dispatch<SetStateAction<string>>;
}
然后將其用作:
return {response: {data, isLoading, isError}, setUrl} as DataApiResponse;
最后在UseDataFetch
方法中進行更改:
const {response, setUrl} = useDataApi(
"https://hn.algolia.com/api/v1/search?query=redux",
{ hits: [] }
);
const {data, isError, isLoading} = response;
或者只是將as const
添加到自定義鈎子中的返回參數。
return [whatever, whatEver] as const
如果 TypeScript 無法推斷它,那么您可以自己顯式聲明函數的返回類型:
// Note return type added after ':'
const useDataApi = (initialUrl:string, initialData: IinitialData<Ihits>): [{data: IinitialData; isLoading: boolean; isError: boolean}, string] => {
const [data, setData] = useState(initialData);
const [url, setUrl] = useState(initialUrl);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await axios(url);
setData(result.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
fetchData();
}, [url]);
// return [{ data, isLoading, isError }, setUrl];
return [{data, isLoading, isError }, setUrl];
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.