reactjs React TypeScript- useData钩子将多个JSON对象发送到前端

6jygbczu  于 2023-05-06  发布在  React
关注(0)|答案(1)|浏览(133)

我尝试使用CodingWithMosh的React Beginner课程中修改过的useData钩子,其中包含多个对象。在课程中,所有的数据都在结果JSON对象中,我想知道如何添加第二个包含数据的对象。
JSON示例

{"titles":{
    "recommend":{
"top": [
    {
        "title_description": "A young Han Solo tries to settle an old score with the help of his new buddy Chewbacca, a crew of space smugglers and a cunning old friend.",
        "title_id": 31536,
        "title_name": "Solo: A Star Wars Story"
    }
],
"new": [
{
        "title_description": " As the remnants of the Resistance flee Kylo Ren and the First Order, Rey seeks out Luke Skywalker – but he wants nothing more to dowith the Force.",
        "title_id": 31571,
        "title_name": "Star Wars: Episode VIII: The Last Jedi"
    }
]
}}}

在我的useData中,我将结果更改为推荐。在测试钩子中,我为调用它而做的,我为这两个对象添加了另一个接口,并将其发送到我的tsx。

import { useEffect, useState } from "react";
import testapi from "../Services/api-test";
import { AxiosRequestConfig, CanceledError } from "axios";

interface FetchResponse<T> {
  count: number;
  recommend: T[];
}

const useData = <T>(
  endpoint: string,
  requestConfig?: AxiosRequestConfig,
  deps?: any[] //dependencies, this is used for querying
) => {
  const [data, setData] = useState<T[]>([]);
  const [error, setError] = useState("");
  const [isLoading, setLoading] = useState(false);

  useEffect(
    () => {
      const controller = new AbortController(); //for cancellations

      setLoading(true);
      testapi
        .get<FetchResponse<T>>(endpoint, {
          signal: controller.signal,
          ...requestConfig,
        })
        .then((res) => {
          setData(res.data.recommend);
          setLoading(false);
        })
        .catch((err) => {
          if (err instanceof CanceledError) return;
          setError(err.message);
          setLoading(false);
        });
      return () => controller.abort();
    },
    deps ? [...deps] : []
  ); 
  return { data, error, isLoading };
};

export default useData;

useTest钩子,我修改了这两个项目

export interface Items {
  top: Test;
  new: Test;
}

export interface Test {
  title_description: string;
  title_id: number;
  title_name: string;
}

//Hook Name = function => useData hook <Object> ("/endpoint")
const useTest = () => useData<Items>("/titles");

export default useTest;

当我尝试Map时,我在控制台中得到一个错误,说“data.map?不是一个函数”Map在tsx中:

{error && <div>{error}</div>}
        {data?.map((title) => (
          <ul key={title.top.title_id} style={{ margin: 0, padding: 0 }}>
            <div className={styles.title} onClick={() => navigate("/title")}>
              {title.top.title_name}
            </div>
          </ul>
        ))}

是不是因为JSON是如何设置的?试图Map到对象而不是数组?我看到console.log(typeof(data))是一个对象,它可能需要是一个数组?谢谢!
编辑:这就是我如何将useTest钩子导入到我的组件中。

const { data, error } = useTest();
5uzkadbs

5uzkadbs1#

从你的JSON示例中可以清楚地看到,你试图通过一个对象进行Map,这是不可能的。您可以使用Object.entries(data)将对象转换为[[key1, value1], [key2, value2]]Object.values(data)的数组,以直接迭代值。如果你想迭代titles -〉recommend -〉top下的所有数据,你可以一个接一个地选择键,直到你到达数据:

data?.titles?.top?.map((title) => (
      <ul key={title.title_id} style={{ margin: 0, padding: 0 }}>
        <div className={styles.title} onClick={() => navigate("/title")}>
          {title.title_name}
        </div>
      </ul>
    ))

相关问题