英文:
Error data type on typescript with next.js
问题 {#heading}
我遇到了一个问题,无法知道从 API 获取的 URL 的数据类型,我正在使用一个自定义 hook 来使其可用。我正在使用 Next.js
和 TypeScript。
这是一个 useFetch.js
(自定义 hook):
import { useState } from "react";
type FetchParams = {
url: any;
};
async function getData(url: FetchParams) {
try {
const res = await fetch(url.toString());
return res.json();
} catch (error) {
console.log("error", error);
}
}
export default async function useFetch(url: FetchParams) {
const [data, setData] = useState("");
setData(await getData(url));
return { data };
}
这是一个 pray 组件:
import useFetch from '@/Hooks/useFetch';
import { useState, useEffect } from 'react';
export default function Pray() {
// Date methods
let date = new Date();
let month = date.getMonth() + 1;
let year = date.getFullYear();
// day equal date - 1
let day = date.getDate() - 1;
const [country, setCountry] = useState('eg');
const [city, setCity] = useState('cairo');
const [data, setData] = useState("");
useEffect(() => {
const { data }: any = useFetch(`https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`);
console.log(data);
}, [data]);
return null;
}
错误信息是:
Argument of type 'string' is not assignable to parameter of type 'FetchParams'.ts(2345)
英文:
I have a problem knowing the data type of the URL that I WILL res API from it, and I am using a custom hook to make it usable I am using Next.js
with typescript
this is a useFetch.js
(custom hook)
"use client"
import { useState } from "react";
type FetchParams = {
url: any
}
async function getData(url: FetchParams) {
try {
const res = await fetch(url.toString())
return res.json()
} catch(error) {
console.log("error", error);
}
}
export default async function useFetch(url: FetchParams) {
const [data, setData] = useState("")
setData(await getData(url))
return { data };
}
This is a pray components
import useFetch from '@/Hooks/useFetch';
import { useState, useEffect } from 'react';
export default function Pray() {
// Date methods
let date = new Date();
let month = date.getMonth() + 1;
let year = date.getFullYear();
// day equal date - 1
let day = date.getDate()-1;
const \[country, setCountry\] = useState(\'eg\')
const \[city, setCity\] = useState(\'cairo\')
const \[data, setData\] = useState(\"\")
useEffect(() =\> {
const { data }: any = useFetch(`https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`)
console.log(data)
}, \[data\])
`return()
}
`
error is:
> Argument of type 'string' is not assignable to parameter of type
> 'FetchParams'.ts(2345)
const { data }: any = useFetch(`https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`)
答案1 {#1}
得分: 2
你已经声明了useFetch
来消耗一个FetchParams
类型的参数,而不是一个字符串类型的参数。
请更新useFetch
以接受一个URL字符串类型的值。不要忘记使用useEffect
钩子来执行发出请求并更新data
状态的副作用。
"use client"
import { useState, useEffect } from "react";
async function getData(url: string) {
try {
const res = await fetch(url);
return res.json();
} catch(error) {
console.log("error", error);
}
}
export default function useFetch(url: string) {
const [data, setData] = useState("");
useEffect(() => {
getData(url).then(setData);
}, [url]);
return { data };
}
或者,您可以传递一个对象:
type FetchParams = {
url: string
}
async function getData(fetchParams: FetchParams){
try {
const res = await fetch(fetchParams.url);
return res.json();
} catch(error) {
console.log("error", error);
}
}
export default function useFetch(fetchParams: FetchParams) {
const [data, setData] = useState("");
useEffect(() => {
getData(fetchParams).then(setData);
}, [fetchParams]);
return { data };
}
const { data }: any = useFetch({
url: `https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`
});
useFetch
钩子***不能*** 在useEffect
钩子的回调函数内部调用。它必须作为组件的顶层或其他自定义React钩子的一部分进行调用。删除data
状态并简单地引用useFetch
钩子返回的值。
export default function Pray() {
// 日期方法
let date = new Date();
let month = date.getMonth() + 1;
let year = date.getFullYear();
// day等于date - 1
let day = date.getDate() - 1;
const [country, setCountry] = useState('eg');
const [city, setCity] = useState('cairo');
const { data }: any = useFetch(
`https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`
);
return (....);
}
英文:
You have declared useFetch
to consume a FetchParams
type argument, not a string type argument.
Update useFetch
to consume a URL string type value. Don't forget to use a useEffect
hook to issue the side-effect of making the fetch and updating the data
state.
"use client"
import { useState } from "react";
async function getData(url: string) {
try {
const res = await fetch(url);
return res.json();
} catch(error) {
console.log("error", error);
}
}
export default async function useFetch(url: string) {
const [data, setData] = useState("");
useEffect(() => {
getData(url).then(setData);
}, [url]);
return { data };
}
Alternatively you could pass an object:
type FetchParams = {
url: string
}
async function getData(fetchParams: FetchParams){
try {
const res = await fetch(fetchParams.toString());
return res.json();
} catch(error) {
console.log("error", error);
}
}
export default async function useFetch(fetchParams: FetchParams) {
const [data, setData] = useState("");
useEffect(() => {
getData(url).then(setData);
}, [fetchParams]);
return { data };
}
const { data }: any = useFetch({
url: `https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`
});
The useFetch
hook can't be called from within the useEffect
hook's callback function. It must be called as the top-level of the component or other custom React hooks. Remove the data
state and simply reference the useFetch
hook's returned value.
export default function Pray() {
// Date methods
let date = new Date();
let month = date.getMonth() + 1;
let year = date.getFullYear();
// day equal date - 1
let day = date.getDate()-1;
const [country, setCountry] = useState('eg');
const [city, setCity] = useState('cairo');
const { data }: any = useFetch(
`https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`
);
return (....);
}
答案2 {#2}
得分: 1
要解决这个问题,您需要将一个对象
而不是一个字符串
作为参数传递给useFetch
:
const {data}: any = useFetch({url: `https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`})
英文:
To fix this, you need to pass an object
instead of a string
to the useFetch
as a parameter:
const {data}: any = useFetch({url: `https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`})
答案3 {#3}
得分: 1
你遇到的错误是因为你将接口分配给了你的对象,然后直接将值传递给它。你的url对象应该像这样:
url:{url:string} 而不是 url:string
所以你需要改变声明对象的方式或将对象作为子对象传递:
以正确的方式声明url对象
export default async function useFetch({url}: FetchParams) {
const [data, setData] = useState("");
setData(await getData(url));
return { data };
}
或者将url放入一个对象中
const {data}: any = useFetch({url: `https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`})
另外,我认为你的useFetch 函数在这里是不必要的,你可以直接调用你的getData函数。 英文:
The error you are getting is because you have assigned the interface to your object and then you are directly passing it value to it. Your url object is something like this:
url:{url:string} instead of being url:string
So you need to change your way of declaring the object or pass your object as a child object:
Declare the url object the correct way
export default async function useFetch({url}: FetchParams) {
const [data, setData] = useState("")
setData(await getData(url))
return { data };
}
Or send url in an object
const {data}: any = useFetch({url: `https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`})
Also I think your useFetch function is unnecessary here, you can just directly call your getData function.