Apologies if this is a simple question, I’m new to React and have been stuck for a while. I have an application that fetches data from the Google Books API and displays it. It’s working fine for everything except the component with useParams().
I have a library of books and I am using Link to route to a page specific to the book clicked on:
<Link className="grid__item__inner" to={/book/${book.id}}>
That routes to this page:
/* Page to display an individual book */
import React, { useEffect, useState } from "react";
import { getBookById } from "../googlebooks";
import { catchErrors } from "../utils";
import { useParams } from "react-router-dom";
import { StyledBookInfo } from "../styles";
const BookInfo = () => {
const { id } = useParams();
const [book, setBook] = useState([]);
useEffect(() => {
const fetchData = async () => {
const { data } = await getBookById(id);
setBook(data);
};
catchErrors(fetchData());
}, [id]);
return (
<>
{book ? (
<>
<p>Keep reading:</p>
<>
<StyledBookInfo>
<h2>{book.volumeInfo.title}</h2>
<h3>By {book.volumeInfo.authors}</h3>
<div class= "flex-cont">
<img
src={book.volumeInfo.imageLinks.thumbnail}
alt={book.volumeInfo.title}
className="cover"
/>
<p className="description">{book.volumeInfo.description.replace(/</?[^>]+(>|$)/g, "")}</p>
</div>
<p>{book.volumeInfo.pageCount} pages</p>
</StyledBookInfo>
</>
</>
) : (
<p>There is NO book</p>
)}
</>
);
};
export default BookInfo`
This works the first time you navigate to the BookInfo page, but any changes/refreshing loses the data and book
is undefined. If you go back to the library and try to navigate to a different book, that also won’t work.
So far the only way I’ve been able to get the data back is by removing all code referencing book, refreshing, and then pasting it back. The setup is really similar to my other working components, the only difference is the useParams(), so I’m wondering if I am using that incorrectly. I read up on localstorage but I dont think that is the proper solution here.
2
Answers
It’s because of how you’re setting the initial state of the book:
An empty array is still "truthy", so it is still triggering the ternary operator in your return. I believe all you need to do is change that line to this:
/In this version of the code, the book data is stored in local storage using the setItem method whenever it is fetched from the API. When the component first mounts, it checks if there is any stored book data in local storage using the getItem method. If there is stored data, it sets the book state to the stored data. Otherwise, it fetches the book data and sets it as state. This way, the book data will persist even if the page is refreshed./