Lesson 6 - Create BookCard.jsx Component
Explanation and Step-by-Step Procedure for BookCard
and BookList
Integration
BookCard
and BookList
IntegrationStep 1: Create BookCard.jsx
BookCard.jsx
The BookCard
component displays individual book details in a card layout.
Key Features of BookCard.jsx
:
Props:
The
book
prop contains all the book details.
Two-Column Layout:
Left Column: Displays the book's thumbnail image.
Right Column: Shows the book title, authors, description, and published year.
Reusable Component:
Uses the
ReadMore
component for expandable descriptions.
Prop Validation:
Ensures that
book
prop matches the expected structure.
// Layout Design of BookCard Component
BookCard Component
│
├── Props
│ └── book (object) - Contains book information
│ └── volumeInfo (object)
│ ├── title (string)
│ ├── authors (array of strings)
│ ├── description (string)
│ ├── publishedDate (string)
│ └── imageLinks (object)
│ └── thumbnail (string)
│
└── Render Structure
└── <div> (card mb-3, maxWidth: '540px')
└── <div> (row g-0)
├── Left Column: <div> (col-md-4) - Book Thumbnail
│ └── <img> (img-fluid rounded-start)
│ ├── src={imageLinks?.thumbnail || 'https://via.placeholder.com/128x200'}
│ └── alt={title || 'No Thumbnail'}
│
└── Right Column: <div> (col-md-8) - Book Details
└── <div> (card-body)
├── <h5> (card-title) - Book title
│ └── {title || 'No Title Available'}
│
├── <p> (card-text) - Authors
│ ├── <strong>Authors:</strong>
│ └── Conditional: {authors ? authors.join(', ') : 'Unknown'}
│
├── <p> (card-text) - Description
│ ├── <strong>Description:</strong>
│ └── Conditional: {description ? <ReadMoreUpdate book={book} /> : 'No Description Available'}
│
└── <p> (card-text) - Published Year
└── <small> (text-muted)
├── <strong>Published Year:</strong>
└── {publishedDate || 'Unknown'}
Step 2: Modify BookList.jsx
BookList.jsx
Integrate the BookCard
component into BookList
for displaying each book's details.
Key Changes in BookList.jsx
:
Import
BookCard
:import BookCard from './BookCard';
This allows
BookList
to use theBookCard
component.
Replace Card Rendering Logic:
{books.map((book) => ( <BookCard key={book.id} book={book} /> ))}
For each book, render a
BookCard
component and pass thebook
object as a prop.
Flexible Layout:
Books are displayed using a
d-flex flex-wrap justify-content-center
class for responsive alignment.
How It Works Together
BookList
:Iterates over the list of books and renders a
BookCard
for each.
BookCard
:Takes a single
book
object and displays its content in a card layout.
Advantages:
Reusability: The
BookCard
component can be reused in other contexts.Separation of Concerns: Cleanly separates rendering logic for individual books.
Benefits for Students
Component Hierarchy:
Understand how to compose larger components from smaller, reusable components.
Bootstrap Layout:
Learn to use
d-flex
andflex-wrap
for responsive layouts.
Reusable Patterns:
Create modular components (
BookCard
) that simplify main component logic.
Step-by-Step Explanation of BookCard.jsx
Implementation
BookCard.jsx
ImplementationThe BookCard
component displays detailed information about a book in a card-style layout.
Step 1. Import Necessary Libraries
import React from 'react';
import PropTypes from 'prop-types';
import ReadMore from './ReadMore';
React: Provides the base framework for building the component.
PropTypes: Ensures the props passed to the component are well-defined.
Bootstrap: Provides ready-to-use styles for the layout.
ReadMore: A component to manage expandable descriptions.
Step 2. Destructure Props
const { title, authors, description, publishedDate, imageLinks } = book.volumeInfo;
Extracts specific fields from the
book.volumeInfo
object for easy access.
Step 3. BookCard Layout
<div className="card mb-3" style={{ maxWidth: '540px' }}>
<div className="row g-0">
{/* Left Column: Thumbnail */}
<div className="col-md-4">
<img
src={imageLinks?.thumbnail || 'https://via.placeholder.com/128x200'}
alt={title || 'No Thumbnail'}
className="img-fluid rounded-start"
/>
</div>
{/* Right Column: Book Details */}
<div className="col-md-8">
<div className="card-body">
<h5 className="card-title">{title || 'No Title Available'}</h5>
<p className="card-text">
<strong>Authors:</strong> {authors ? authors.join(', ') : 'Unknown'}
</p>
<p className="card-text">
<strong>Description:</strong> {description ? <ReadMore text={description} /> : 'No Description Available'}
</p>
<p className="card-text">
<small className="text-muted">
<strong>Published Year:</strong> {publishedDate || 'Unknown'}
</small>
</p>
</div>
</div>
</div>
</div>
Left Column:
Displays the book's thumbnail image.
If the image is unavailable, a placeholder is used.
Right Column:
Contains details such as title, authors, description, and published year.
Uses
ReadMore
for expandable descriptions.
Step 4. Prop Validation
BookCard.propTypes = {
book: PropTypes.shape({
volumeInfo: PropTypes.shape({
title: PropTypes.string,
authors: PropTypes.arrayOf(PropTypes.string),
description: PropTypes.string,
publishedDate: PropTypes.string,
imageLinks: PropTypes.shape({
thumbnail: PropTypes.string,
}),
}).isRequired,
}).isRequired,
};
Ensures the
book
prop contains all necessary fields with correct types.
5. Export the Component
export default BookCard;
Makes
BookCard
reusable across the application.
Integration with BookList
BookList
The
BookList
component usesBookCard
to render individual book details.For each book in the list, a
BookCard
is created with the book object as a prop.
Benefits for Students
Reusability:
The modular
BookCard
can be reused wherever book details need to be displayed.
Responsive Design:
The Bootstrap-based layout adapts to different screen sizes.
Clean Code:
Prop validation ensures better maintainability and error checking.
This implementation completes the integration of BookCard
with the app.
Last updated