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.jsxThe BookCard component displays individual book details in a card layout.
Key Features of BookCard.jsx:
Props:
The
bookprop 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
ReadMorecomponent for expandable descriptions.
Prop Validation:
Ensures that
bookprop 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.jsxIntegrate the BookCard component into BookList for displaying each book's details.
Key Changes in BookList.jsx:
Import
BookCard:import BookCard from './BookCard';This allows
BookListto use theBookCardcomponent.
Replace Card Rendering Logic:
{books.map((book) => ( <BookCard key={book.id} book={book} /> ))}For each book, render a
BookCardcomponent and pass thebookobject as a prop.
Flexible Layout:
Books are displayed using a
d-flex flex-wrap justify-content-centerclass for responsive alignment.
How It Works Together
BookList:Iterates over the list of books and renders a
BookCardfor each.
BookCard:Takes a single
bookobject and displays its content in a card layout.
Advantages:
Reusability: The
BookCardcomponent 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-flexandflex-wrapfor 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.volumeInfoobject 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
ReadMorefor 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
bookprop contains all necessary fields with correct types.
5. Export the Component
export default BookCard;Makes
BookCardreusable across the application.
Integration with BookList
BookListThe
BookListcomponent usesBookCardto render individual book details.For each book in the list, a
BookCardis created with the book object as a prop.
Benefits for Students
Reusability:
The modular
BookCardcan 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