에러해결기

Array.map is not a function (인자잘못지정 /배열이 아닌값을 넣었을때)

hihiha2 2023. 4. 18. 19:40

googlebooks의 API를 가져오는 과정에서 

Array.map is not a function 라는 에러가 발생하며, map을 사용할 수가 없다는 에러가 나왔다.

 

원래는 잘 작동하던 코드였는데 axios를 모듈화하여 따로 빼주는 과정에서 이런 에러가 발생했다. 

해결하느라 꽤 시간이 걸렸지만 이유를 알고나니, 해결방법은 완전 간단했다.

 

🔍 원인

Array.map is not a function 에러는 배열이 아닌값을 map()을 돌리면 발생한다.

나의 경우 bookData를 불러오는 과정에서 경로를 더 들어가야하는데, 그냥 response를 그대로 받아오게 했더니 이런 에러가 발생하였다.

 

  

 

✅ 해결

console.log(res);

를 통해서 받아오는 값을 확인한다.

 

개발자도구-콘솔창을 열어서 확인을 하면

이런식으로 받아오는 값의 경로를 볼수가 있다.

 

data.items의 안에 있는 정보들을 map()을 돌면서 받아와야하기 때문에

나의 경우는 res가 아니라, res.data.items와 같이 코드를 수정해야했다.

 

 

❌ 이전코드  

  const handleSubmitSearch = () => {
    getBookData(search).then((res) => {
      console.log(res);
      setBookData(res);
    });
  };

 

🙆‍♂️ 수정한 코드 🙆‍♂️

 const handleSubmitSearch = () => {
    getBookData(search).then((res) => {
      console.log(res);
      setBookData(res.data.items);
    });
  };

 

res ➡️ res.data.items

 

 

 

👍 이렇게 하면 map()이 아주 잘 작동하는 것을 볼 수 있다.

 

 

🕵️‍♀️ 느낀점

해결방법을 찾아보니 엄청 생각보다 간단했는데, 위쪽에 데이터를 받아오는 곳을 수정했어야 했는데 코드아래쪽의 map근처만 고칠려고 해서 시간이 오래걸렸다..!! 구글링이 살길이다 ㅎㅎ 그래도 앞으로는 같은 에러가 나오면 이유가 뭔지를 알아서 더 빨리 에러를 잡을 수 있을 것같다. 😄

 

 

 

💻 전체코드

//main.js

import React, { useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";
import BookCard from "../BookCard/BookCard.js";
import ChatGPT from "../ChatGPT/ChatGPT.js";
import "./Main.css";
import BookDetailModal from "../BookDetailModal/BookDetailModal.js";
import bookicon from "../../assets/bookicon.png";
import { getBookData } from "../../API/Apis.js";

export default function Main() {
  const [search, setSearch] = useState("");
  const [bookData, setBookData] = useState([]);
  const [selectedBook, setSelectedBook] = useState(null);

  const handleSubmitSearch = () => {
    getBookData(search).then((res) => {
      console.log(res);
      setBookData(res.data.items);
    });
  };

  const handleCloseBookDetailModal = () => {
    setSelectedBook(null);
  };

  return (
    <>
      <div className="header">
        <div className="row1">
          <h1>BooksBooks</h1>
        </div>
        <div className="row2">
          <img className="book-icon" src={bookicon} alt="book-icon" />
          <h2>TodayBook</h2>
          <h3>"What book should I read today?"</h3>
          <div className="search">
            <input
              type="text"
              placeholder="책이름을 입력하세요"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              onKeyPress={(e) => {
                if (e.key === "Enter") {
                  handleSubmitSearch();
                }
              }}
            />
            <button onClick={handleSubmitSearch}>
              <FontAwesomeIcon icon={faMagnifyingGlass} />
            </button>
          </div>
          <div className="chat-title">
            <h3>책에 대해 궁금한거 물어보세요!!</h3>
          </div>
          <div className="chat-box">
            <ChatGPT />
          </div>
        </div>
      </div>

      <div className="container">
        {bookData.map((books) => {
          if (
            books.volumeInfo?.imageLinks?.smallThumbnail &&
            books.saleInfo?.listPrice?.amount &&
            books.volumeInfo?.title
          ) {
            return <BookCard books={books} setSelectedBook={setSelectedBook} />;
          }
        })}
        {selectedBook && (
          <BookDetailModal
            selectedBook={selectedBook}
            onClose={handleCloseBookDetailModal}
          />
        )}
      </div>
    </>
  );
}