【问题标题】:TypeError: Cannot read property 'map' of undefined in react-hooksTypeError:无法读取反应挂钩中未定义的属性“地图”
【发布时间】:2021-04-12 21:30:56
【问题描述】:

我是初学者。提前感谢您分享您的知识。

这个错误最初没有出现。

但即使他们使用相同的代码,它现在也出现了。

什么原因?

虽然通过Api接收到的数据是数组的形式,但是'map'方法不起作用。

我阅读了另一个相同的问题,但我无法解决这个问题。

这个错误困扰了我一天。让我知道我必须做什么。

import React, { useState, useEffect } from "react";
import axios from "axios";
import styled from "styled-components";

const MyModal = ({ onClose, selectedItem }) => {
  const [data, setData] = useState([]);
  let id = selectedItem;
  let url = `https://www.thecocktaildb.com/api/json/v1/1/lookup.php?i=${id}`;
  useEffect(() => {
    axios
      .get(url)
      .then((res) => {
        setData(res.data.drinks);
      })
      .catch((error) => {
        console.log(error);
      });
  }, [url]);
  return (
    <MyModals onClick={onClose}>
      <Wrapper>
        <button onClick={onClose}>X</button>
        {data.map((result) => { ???? This is the part of the problem.
          return (
            <Container>
              <Image>
                <img src={result.strDrinkThumb} alt={result.idDrink} />
              </Image>
              <About>
                <Name>{result.strDrink}</Name>
            </Container>
          );
        })}
      </Wrapper>
    </MyModals>
  );
};

export default MyModal;

同样,这个文件也有同样的问题。错误出现然后出现。

import React, { useState, useEffect } from "react";
import styled from "styled-components";
import Portal from "../Components/Portal";
import Modal from "../Components/Modal";

const Search = () => {
  const [searchTerm, setSearchTerm] = useState("a");
  const [cocktails, setCocktails] = useState([]);
  const [open, setOpen] = useState(false);
  const [selectedItem, setSelectedItem] = useState("");

  const handleOpen = (idDrink) => {
    setSelectedItem(idDrink);
    setOpen(true);
    console.log("open");
  };

  const handleClose = () => {
    setOpen(false);
    console.log("close");
  };
  useEffect(() => {
    const getDrinks = async () => {
      try {
        const response = await fetch(
          `https://www.thecocktaildb.com/api/json/v1/1/search.php?s=${searchTerm}`
        );
        const data = await response.json();
        setCocktails(data);
      } catch (error) {
        console.log(error);
      }
    };
    getDrinks();
    console.log("useEffect");
  }, [searchTerm]);

  return (
    <main style={{ width: "100%" }}>
      <SearchForm setSearchTerm={setSearchTerm} />
      <Wrapper className="cocktail-list">
        {cocktails &&
          cocktails.drinks.map(({ idDrink, strDrink, strDrinkThumb }) => (
            <Container
              className="cocktail"
              onClick={() => {
                handleOpen(idDrink);
              }}
            >
              <Img>
                <img src={`${strDrinkThumb}`} alt={`${strDrink}`} />
              </Img>
              <Name key={`${idDrink}`}>{`${strDrink}`}</Name>
            </Container>
          ))}
      </Wrapper>
      {open && (
        <Portal>
          <Modal selectedItem={`${selectedItem}`} onClose={handleClose} />
        </Portal>
      )}
    </main>
  );
};

export default Search;

我接收Api数据的部分有问题吗?

import React from "react";
import styled from "styled-components";
import { useState, useEffect } from "react";
import Search from "./Search";
import Modal from "../Components/Modal";
import Portal from "../Components/Portal";

const Main = () => {
  const url = "https://www.thecocktaildb.com/api/json/v1/1/random.php";
  const [data, setData] = useState([]);
  const [open, setOpen] = useState(false);
  const [selectedItem, setSelectedItem] = useState("");

  useEffect(() => {
    const fetchUrl = async () => {
      try {
        const response = await fetch(url);
        const json = await response.json();
        setData(json);
      } catch (error) {
        console.log(error);
      }
    };
    console.log("useEffect");
    fetchUrl();
  }, []);

  const handleOpen = (idDrink) => {
    setSelectedItem(idDrink);
    setOpen(true);
    console.log("open");
  };
  const handleClose = () => {
    setOpen(false);
    console.log("close");
  };

  return (
    <Wrapper className="main">
      {data &&
        data.drinks.map(({ idDrink, strDrink, strDrinkThumb }) => (
          <>
            <Container
              onClick={() => {
                handleOpen(idDrink);
                console.log(handleOpen(idDrink));
              }}
            >
              <img src={`${strDrinkThumb}`} alt={`${strDrink}`} />
              <div key={`${idDrink}`}>{`${strDrink}`}</div>
            </Container>
            {open && (
              <Portal>
                <Modal selectedItem={`${selectedItem}`} onClose={handleClose} />
              </Portal>
            )}
          </>
        ))}
      <Search />
    </Wrapper>
  );
};
export default Main;

错误发生在所有写'map'方法的文件中。

我真的不知道问题是什么。帮帮我!

【问题讨论】:

  • 看起来有一个案例 res.data.drinks 不是数组,因此您可能需要避免设置列表状态,以防出现错误
  • fetch在某些情况下可以拒绝,您需要在访问JSON数据之前检查response.ok。您是否检查过您的网络选项卡,您正在获取有效数据? react映射错误之前是否还有其他错误?
  • 不,没有其他错误。当我在控制台上检查时,出现了 [{...}]。数据已排列。
  • "在控制台上检查"是什么意思?在更新状态之前,您在某处记录了有效响应?你在哪里记录了什么?
  • 仅供参考,有效的响应可以包括{ "drinks": null },所以可以先检查响应,如果drinks 不为空,则仅更新状态。其他 GET 请求也一样。尽量确保你不会改变你的状态对象类型。

标签: reactjs api methods react-hooks


【解决方案1】:

这是因为您的 map() 在数据来自 API 之前调用。所以我建议先完成 API 调用,让数据正常来。然后你应该映射。你可以使用-

{data && data.map((result) => { ? This will solve ur problem
      return (
        <Container>
          <Image>
            <img src={result.strDrinkThumb} alt={result.idDrink} />
          </Image>
          <About>
            <Name>{result.strDrink}</Name>
        </Container>
      );
    })}

【讨论】:

  • data 的初始状态是一个空数组,所以我不认为这是分辨率。
  • ``` const fetchUrl = () => { axios .get(url) .then((res) => { setData(res.data.drinks); }) .catch((error ) => { console.log(error); }); }; useEffect(() => { fetchUrl(); }, []); ```我的理解正确吗?
  • 如果数据正确,我的代码将解决您的问题,但正如我所见,thecocktaildb.com/api/json/v1/1/lookup.php?i=${id} 没有返回任何内容。你能正确检查网址吗?
【解决方案2】:

确保来自 API 的数据是有效的数组,您可以使用 Array.isArray() 进行检查。

代码可能是这样的:

{Array.isArray(data) &&
  data.map(result => (
    <Container>
      <Image>
        <img src={result.strDrinkThumb} alt={result.idDrink} />
      </Image>
      <About />
      <Name>{result.strDrink}</Name>
    </Container>
  ))}

【讨论】:

    猜你喜欢
    • 2020-06-30
    • 2019-09-04
    • 1970-01-01
    • 2021-12-02
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 2021-08-28
    相关资源
    最近更新 更多