首页 > 解决方案 > 如何在打字稿中调用使用钩子的函数?

问题描述

我试图将打字稿(我当然是新的)添加到我的反应项目中。我写了一个从我写的 api 获取数据的钩子。我想添加类型,但我认为由于渲染开始时未定义状态,打字稿不会编译。我正在猜测。问题在于在 VictoryPie 组件中调用 formatData 函数。我得到的错误是:

TypeScript error: Argument of type 'boolean | never[]' is not assignable to parameter of type 'Data[]'.
  Type 'false' is not assignable to type 'Data[]'.  TS2345

    26 |         <VictoryPie
    27 |           colorScale={['tomato', 'orange', 'gold', 'cyan', 'navy']}
  > 28 |           data={formatData(graphData)}
       |                            ^
    29 |           x="description"
    30 |           y="amount"
    31 |         />
import React from 'react';
import {useFetch} from '../hooks';
import {VictoryPie} from 'victory';

interface Data {
  _id: number,
  id: string,
  userName: string,
  amount: number,
  description: string,
  time: string,
}

const Graph = () => {
  const [graphData, loading] = useFetch('/api/Kamil');
  const formatData = (inputData: Array<Data>) => {
    return inputData.map(
      ({_id, id, time, userName, ...keepAttrs}) => keepAttrs,
    );
  };
  return (
    <>
      {loading ? (
        'Loading...'
      ) : (
        <VictoryPie
          colorScale={['tomato', 'orange', 'gold', 'cyan', 'navy']}
          data={formatData(graphData)}
          x="description"
          y="amount"
        />
      )}
    </>
  );
};
export default Graph;

import {useState, useEffect} from 'react';
import axios from 'axios';

function useFetch(url: string) {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);
  async function fetchUrl() {
    const response = await axios(url);
    console.log(response);
    setData(response.data)
    setLoading(false);
  }
  useEffect(() => {
    fetchUrl();
  }, []);
  return [data, loading];
}
export { useFetch };

标签: reactjstypescript

解决方案


这里有2个问题。

您需要声明您的钩子返回元组。现在打字稿假设您正在返回数据数组并以任何顺序加载。

此外,您需要声明您期望什么样的结果作为获取结果。

你的钩子应该看起来像

function useFetch<ExpectedResult>(url: string, initialData: ExpectedResult): [ExpectedResult, boolean] {
  const [data, setData] = useState(initialData);
  const [loading, setLoading] = useState(true);

  async function fetchUrl() {
    const response = await axios(url);
    console.log(response);
    setData(response.data)
    setLoading(false);
  }
  useEffect(() => {
    fetchUrl();
  }, [url]); // <<-- when url is changed you propably want to re-fetch
  return [data, loading];
}

然后当你使用它时

做它喜欢

type DataFromServer = Date[];

const [data, isLoading] = useFetch<DataFromServer>('/api/Kamil', []);

现在打字稿知道[data, isLoading]应该是什么。


推荐阅读