网站搜索

reactjs - 在使用 next.js 的 typescript 中的数据类型错误


我在确定我将从其调用 API 的 URL 的数据类型时遇到了问题,我正在使用一个自定义 Hook 来使其可用,我使用的是 Next.js 和 TypeScript

这是一个 useFetch.js(自定义 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 };
}

这是祈祷的组成部分

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}`)

答案#1

你已经声明 useFetch 来接收一个 FetchParams 类型的参数,而不是字符串类型的参数。

更新 useFetch 以使用 URL 字符串类型的值。别忘了使用 useEffect 钩子来执行获取数据的副作用,并更新 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 钩子 不能 在 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 (....);
}

答案#2

你收到的错误是因为你已经将接口分配给你的对象,然后你直接将值传递给它。你的 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 函数。