I'm trying to display a book review when someone clicks on any of the book images (onClick function) which should take them to the book review page of that particular book in a new route. I loaded the book covers manually in Books.js and then displayed the individual book cover in Book.js.
Any help is appreciated.
Books.js:
import React from "react";
import atomicHabits from "../../../assets/images/books/atomicHabits.jpg";
import fourhourworkweek from "../../../assets/images/books/4-hour-work-week.jpg";
import almanack from "../../../assets/images/books/alamanack-naval.jpg";
import richDadPoorDad from "../../../assets/images/books/richDadPoorDad.jpg";
import lawsOfPower from "../../../assets/images/books/48LawsOfPower.jpg";
import showYourWork from "../../../assets/images/books/showYourWork.jpg";
import Book from "./Book";
const Books = () => {
const books = [
{
_id: 1,
name: "The 4-Hour Work Week",
description: "ABCD",
img: lawsOfPower,
},
{
_id: 2,
name: "Rich Dad Poor Dad",
description: "EFGH",
img: richDadPoorDad,
},
{
_id: 3,
name: "Show Your Work",
description: "IJKL",
img: showYourWork,
},
{
_id: 4,
name: "Atomic Habits",
description: "IJKL",
img: atomicHabits,
},
{
_id: 5,
name: "The Almanack of Naval Ravikant",
description: "IJKL",
img: almanack,
},
{
_id: 6,
name: "The 4-Hour Work Week",
description: "IJKL",
img: fourhourworkweek,
},
];
return (
<div id="bookshelf">
<div className="font-bold text-3xl mt-24 mb-8">
<h3>My Bookshelf</h3>
</div>
<div className="grid sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-10 ">
{books.map((book) => (
<Book key={book._id} book={book}></Book>
))}
</div>
</div>
);
};
export default Books;
Book.js:
import React from "react";
import "./Book.css";
const Book = ({ book }) => {
const { _id, name, img, description } = book;
return (
<div className="card book-container card-compact w-56 bg-base-100 shadow-2xl">
<figure>
<img className="h-full w-full" src={img} alt="Books" />
</figure>
</div>
);
};
export default Book;
CodePudding user response:
If you are using react router, you can use useNavigate hook for e.g
const navigate = useNavigate(); // declared at the top level
<figure onClick={()=> navigate(`/book-review-route/{id}`)}>
<img className="h-full w-full" src={img} alt="Books" />
</figure>
CodePudding user response:
You can either issue a declarative navigation with the Link
component:
import React from "react";
import { Link } from "react-router-dom";
import "./Book.css";
const Book = ({ book }) => {
const { _id, name, img, description } = book;
return (
<div className="card book-container card-compact w-56 bg-base-100 shadow-2xl">
<figure>
<Link to={`/book/${_id}`}>
<img className="h-full w-full" src={img} alt="Books" />
</Link>
</figure>
</div>
);
};
Or issue an imperative navigation with the navigate
function via the useNavigate
hook and an attached click handler:
import React from "react";
import { useNavigate } from "react-router-dom";
import "./Book.css";
const Book = ({ book }) => {
const navigate = useNavigate();
const { _id, name, img, description } = book;
return (
<div className="card book-container card-compact w-56 bg-base-100 shadow-2xl">
<figure>
<img
className="h-full w-full"
src={img}
alt="Books"
role="link"
onClick={() => navigate(`/book/${_id}`)}
/>
</figure>
</div>
);
};
Using the Link
is the more HTML semantically correct and accessible way to link to another page, if you use an onClick
handler then you'll want to specify any additional accessibility attributes to ensure your app is accessible to screen readers and other accessibility tools.