【问题标题】:TypeError: Cannot read property 'map' of undefined while fetching from APITypeError:从 API 获取时无法读取未定义的属性“地图”
【发布时间】:2021-07-13 12:36:21
【问题描述】:

我一直在尝试进行简单的 API 提取,但我不明白我做错了什么 我已经阅读了很多问题,但我真的觉得我错过了一些东西,因为一切似乎都是正确的(显然不是)

import { useState } from "react";
import ProductCard from "./ArticleCard/ProductCard.js";

export default function ProductsIndex() {
  const [searchText, set_searchText] = useState("");
  const [state, set_state] = useState({ status: "idle" });
  const search = async () => {
    if (searchText === "") {
      set_state({ status: "idle" });
      return;
    }
    set_state({ status: "searching" });
    const queryParam = encodeURIComponent(searchText);
    const data = await fetch(
      /* base browser fetch  https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch*/
      `https://omdbapi.com/?apikey=6a06f383&s=${queryParam}`
    ).then((r) => r.json());
    set_state({ status: "done!", data: data.Search });
  };
  console.log(state.data);
  return (
    <div className="ProductsIndex">
      We sell movies for a high price.
      <h1>Discover some movies!</h1>
      <p>
        <input
          value={searchText}
          onChange={(e) => set_searchText(e.target.value)}
        />
        <button onClick={search}>Search</button>
      </p>{" "}
      <p>
        {state.data.map((movie) => (
          <ProductCard
            poster={movie.poster}
            title={movie.title}
            year={movie.year}
            type={movie.type}
          />
        ))}
      </p>
    </div>
  );
} 

console.log(state.data) 给出了想要的结果,所以就好像数据没有被传递..我不明白为什么

console.log(state.data) 的结果:

[
    {
        "Title": "Finding Nemo",
        "Year": "2003",
        "imdbID": "tt0266543",
        "Type": "movie",
        "Poster": "https://m.media-amazon.com/images/M/MV5BZTAzNWZlNmUtZDEzYi00ZjA5LWIwYjEtZGM1NWE1MjE4YWRhXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_SX300.jpg"
    },
    {
        "Title": "Finding Nemo",
        "Year": "2003",
        "imdbID": "tt0401422",
        "Type": "game",
        "Poster": "https://m.media-amazon.com/images/M/MV5BNGEzMjdiZGEtYzU3ZC00OGFmLWI3NTgtZTcyNTFjYTliNDg5XkEyXkFqcGdeQXVyNjExODE1MDc@._V1_SX300.jpg"
    },
    {
        "Title": "Finding Nemo Submarine Voyage",
        "Year": "2007",
        "imdbID": "tt1319713",
        "Type": "movie",
        "Poster": "https://m.media-amazon.com/images/M/MV5BMzAxMzMyODQtNWY0Yy00N2M3LWE5MDQtZDUzNjc1ZGFmMzA4XkEyXkFqcGdeQXVyMzkxMzc4Mw@@._V1_SX300.jpg"
    },
    {
        "Title": "Finding Nemo: Studio Tour of Pixar",
        "Year": "2003",
        "imdbID": "tt1248974",
        "Type": "movie",
        "Poster": "N/A"
    },
    {
        "Title": "Finding Nemo: A Filmmakers' Roundtable",
        "Year": "2012",
        "imdbID": "tt10255922",
        "Type": "movie",
        "Poster": "https://m.media-amazon.com/images/M/MV5BNjAyMTBmODQtZGYxMC00NjdhLThhN2MtODlhMDI4NTczYTMyXkEyXkFqcGdeQXVyNDEyNjEzOTg@._V1_SX300.jpg"
    }
]

感谢您的帮助

【问题讨论】:

    标签: javascript reactjs array.prototype.map


    【解决方案1】:

    你应该初始化state.data 试试这样。

     const [state, set_state] = useState({ status: "idle",data:[] });
    

    【讨论】:

    • 嘿!感谢您的回答!我实现了它,但它不起作用:(在{state.data.map((movie) =&gt; ( 仍然有同样的错误
    【解决方案2】:

    我刚刚解决了几件事:

    1. 定义数据状态

    const [state, set_state] = useState({ status: "idle",data:[] });

    1. 在迭代之前检查你的数组

      {state.data && state.data.map((movie) => (
         <ProductCard
           poster={movie.poster}
           title={movie.title}
           year={movie.year}
           type={movie.type}
         />
       ))}
      

    我创建了一个小演示:搜索 nemo,按下按钮,请检查控制台,https://codesandbox.io/s/flamboyant-dubinsky-3bxsf?file=/src/App.js:155-219

    【讨论】:

    • 天哪,它修好了!太感谢了!我知道我们在互操作之前检查数组,但为什么这是必要的?是因为 react 比 API“更快”并且它阻止它映射未定义的?再次感谢
    • 组件第一次渲染时,API没有被命中,但它会尝试迭代到未定义的state.data。我们需要在未定义时停止该迭代。 :)
    • 这清除了它,非常感谢!赞成一切:)
    【解决方案3】:

    我想我知道问题所在了!!! 当您设置一个新状态时,它会替换之前的状态。 考虑到这一点,当您像这样设置加载状态时:

    
    set_state({ status: "idle" });
    

    它实际上使您的 state.data 未定义,因此,它会引发异常。

    与其重新分配整个状态,不如尝试仅替换需要更改的内容:

    set_state({ ...state, status: "idle" });
    

    所以,每当你调用你的 set_state 方法时,你应该添加你的...state,这样你就不会有这个问题了。

    【讨论】:

      猜你喜欢
      • 2021-12-20
      • 2020-06-20
      • 1970-01-01
      • 2021-11-09
      • 2021-06-25
      • 1970-01-01
      • 2022-01-12
      • 2022-01-14
      • 2019-03-02
      相关资源
      最近更新 更多