googlebooks의 API를 가져오는 과정에서
Array.map is not a function 라는 에러가 발생하며, map을 사용할 수가 없다는 에러가 나왔다.
원래는 잘 작동하던 코드였는데 axios를 모듈화하여 따로 빼주는 과정에서 이런 에러가 발생했다.
해결하느라 꽤 시간이 걸렸지만 이유를 알고나니, 해결방법은 완전 간단했다.
🔍 원인
Array.map is not a function 에러는 배열이 아닌값을 map()을 돌리면 발생한다.
나의 경우 bookData를 불러오는 과정에서 경로를 더 들어가야하는데, 그냥 response를 그대로 받아오게 했더니 이런 에러가 발생하였다.
✅ 해결
를 통해서 받아오는 값을 확인한다.
개발자도구-콘솔창을 열어서 확인을 하면
이런식으로 받아오는 값의 경로를 볼수가 있다.
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>
</>
);
}