错误的数据类型在使用 TypeScript 和 Next.js 时。

huangapple go评论110阅读模式
英文:

Error data type on typescript with next.js

问题

我遇到了一个问题,无法知道从 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

得分: 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

得分: 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

得分: 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.

huangapple
  • 本文由 发表于 2023年8月10日 15:40:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76873565.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定