Reputation: 67
Pretty new to React, still learning. I was trying to make this Book Finder app using Google Books API, and then when I wanted to map the data, first time everything worked perfectly, but after that one time I started getting this error:
Keep in mind that the first time I ran the code everything worked, I was even fixing some CSS properties and it re-rendered fine. I tried a lot of things, I do know that you can't use .map on objects, and I checked, the API data was and object.
Result of typeof() for the given API data
Heres the code:
MainContainer.tsx
import { useState } from "react";
import List from "./List";
import Search from "./Search";
import request from "superagent";
export default function MainContainer() {
const [books, setBooks] = useState([]);
function handleChange(e: any) {
setBooks(e.target.value);
}
function handleSearch(e: any) {
e.preventDefault();
request
.get("https://www.googleapis.com/books/v1/volumes")
.query({ q: setBooks })
.then((data) => {
setBooks([...books])
})
}
return (
<div className="main-container">
<Search
handleChange={handleChange}
handleSearch={handleSearch}
/>
<List books={books}/>
</div>
)
}
List.tsx
import Card from "./Card"
export default function List(props: any) {
return (
<div className="list-container">
{
props.books && props.books.length > 0 ?
props.books.map(function (book: any) {
return (
<Card
key={book.id}
image={book.volumeInfo.imageLinks.smallThumbnail}
title={book.volumeInfo.title}
author={book.volumeInfo.authors}
published={book.volumeInfo.publishedDate}
/>
)
}) : <p className="np-data">No books yet...</p>
}
</div>
)
}
Card.tsx
export default function Card(props: any) {
return (
<div className="card">
<img src={props.image} alt="" />
<div className="card-desc">
<h3 className="title">{props.title}</h3>
<h4 className="author">{props.author}</h4>
<p className="published">{props.published}</p>
</div>
</div>
)
}
Again, I'm still learning React, this might be some dumb-typo-begginer error so yeah. Thanks in advance!
Upvotes: 0
Views: 101
Reputation: 1677
The problem is that you have two pieces of state here (the search query and the list of books), but you are using a single variable (books
) to keep track of both.
In the MainContainer
component, add this to create another state variable.
const [query, setQuery] = useState('');
Update handleChange
to this to update the search query variable.
function handleChange(e: any) {
setQuery(e.target.value);
}
Update handleSearch
to this to make a request with the last entered query and correctly set the books
state variable.
function handleSearch(e: any) {
e.preventDefault();
request
.get("https://www.googleapis.com/books/v1/volumes")
.query({ q: query})
.then((data) => {
setBooks(data.items)
})
}
It should work as expected now.
Upvotes: 1