reactjs - نوع داده خطا در تایپاسکریپت با next.js
من مشکل دارم در شناخت نوع دادهی URL که از آن API دریافت خواهم کرد، و من از یک هوک سفارشی استفاده میکنم تا قابل استفاده باشد. من از Next.js با تایپاسکریپت استفاده میکنم
این یک useFetch.js (هوک سفارشی) است
"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 };
}
این اجزای نماز است
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()
}
خطا این است:
آرگومان از نوع 'string' قابل اختصاص به پارامتر از نوع 'FetchParams' نمیباشد. ts(2345)
const { data }: any = useFetch(`https://api.aladhan.com/v1/calendarByCity?city=${city}&country=${country}&method=5&month=${month}&year=${year}`)
پاسخ شماره ۱
شما useFetch را به گونهای اعلام کردهاید که یک آرگومان از نوع FetchParams میگیرد، نه یک آرگومان از نوع رشته.
بهروزرسانی useFetch برای استفاده از یک مقدار رشتهای URL. فراموش نکنید از هوک useEffect برای ایجاد اثر جانبی انجام fetch و بهروزرسانی وضعیت data استفاده کنید.
"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 };
}
به طور جایگزین میتوانید یک شیء ارسال کنید:
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}`
});
هوک useFetch نمیتواند از داخل تابع callback هوک useEffect فراخوانی شود. باید در سطح بالای کامپوننت یا سایر هوکهای سفارشی React فراخوانی شود. وضعیت data را حذف کنید و به سادگی به مقدار بازگشتی از هوک useFetch ارجاع دهید.
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 (....);
}
پاسخ شماره ۲
خطایی که دریافت میکنید به این دلیل است که شما اینترفیس را به شیء خود اختصاص دادهاید و سپس مستقیماً مقدار به آن میدهید. شیء url شما چیزی شبیه این است:
url:{url:string} instead of being 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 خود را فراخوانی کنید.
