开发者问题收集

TypeError:无法读取 react-hooks 中未定义的属性“map”

2021-01-07
165

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

这个错误最初并没有出现。

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

原因是什么?

虽然通过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' 方法的文件中都出现了错误。

我真的不知道问题出在哪里。帮帮我吧!

2个回答

发生这种情况是因为您的 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>
      );
    })}
Kousik Sen
2021-01-07

确保来自 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>
  ))}
Jack Chen
2021-01-07