ReactJS-The Beginner Master Class
  • React In the Beginning
    • Lesson 1 - Demo: Build a Simple React App - Fast
    • Lesson 2 - HTML Review
    • Lesson 3 - CSS Review
    • Lesson 4 - Modern JavaScript (JSX) Patterns
    • Lesson 5 - Set up Dev Environment
    • Hands-on Practice
  • React Fundamentals
    • Lesson 1 - Understanding Old vs New Way of Building Web Apps - SPAs
    • Lesson 2 - Motivation for Using React as the Solution to Vanilla JS
    • Lesson 3 - What is ReactJS - How it Works
    • React Code Along from Scratch
    • Lesson 4 - Create and Run a React Project with Vite - Full Overview
    • Lesson 5 - Create Hook by State Management in React
    • Lesson 6 - React Project File and Folder Walkthrough
    • Lesson 7 - JSX and How React Treats the DOM & JSX Compilation(by Babeljs) - Overview
    • Lesson 8 - Understanding the Main Files - App.jsx and main.jsx
    • Lesson 9 - Props and One-Way Data Flow - Overview
    • Lesson 10 - Google Bookshelf App - Ver 1.0
    • Hands-on Practice I
    • Hands-on Practice II
  • React State and Styling
    • Lesson 1 - Pulling Book Data from a Different Data File
    • Lesson 2 - Overview of How State Works in React
    • Lesson 3 - RandomQuote App
    • Lesson 4 - Lifting State Up - React Pattern Overview
    • Hands-On - Simple Counter
  • Forms and Interactivity - Grocery List App
    • Lesson 1 - Setup a Simple Form and Input
    • Lesson 2 - Build Form Profile App Using Multi-input Form Data
    • Hands-on : Build a Grocery List App
  • Connecting to the Backend - Consuming APIs - UseEffect Hook
    • Lesson 1 - Connecting to the Back End - Understanding Side Effects, Hooks and useEffect - Overview
    • Lesson 2 - Fetching Data from the Backend the Right Way with useEffect Hook
    • Lesson 3 - Setting Up Loading State
    • Hands-on :Use Dependency Array and Adding Values that Control Side Effects
  • Solo Project 1
  • RESTful APIs :Build a BookSearch App -Ver 2.0
    • Lesson 1: Build and test RESTful APIs with Postman
    • Lesson 2 - BookShelf App Structure
    • Lesson 3 - Create NavBar.jsx Component
    • Lesson 4 - Create Footer Component
    • Lesson 5 - Create BookList.jsx Component
    • Lesson 6 - Create BookCard.jsx Component
    • Lesson 7 - Creating Custom Hooks - useBooks and api-client
    • Lesson 8 - Controlling Network Activities in React with AbortController
    • Lesson 9 - Show Book Details in a Modal - Working
    • Lesson 10 - Bookshelf App Summary
  • Multi-Page Applications (MPAs)
    • Build a Multi-Page React Application
    • Multi-Page React Application
    • Hands-on Practice
  • Backend Frameworks-NEXT.JS
    • Migrating from React to Next.js
    • Lesson 1: Key Concepts of NodeJS and Express for Backend Web Development
    • Lesson 2: How to set up a new Next.js project
    • Lesson 3: How to create Layouts and Pages
    • Hands-on Practice 1
    • Hands on Practice 2
      • New Project & Folder Structure
      • File-Based Routing
      • Server vs Client Components & Router Hooks
      • Start On The Navbar
      • Navbar Links, Dropdowns & React Icons
      • Active Links & Conditional Rendering
      • Homepage Components
      • Properties Page
      • Property Card Dynamic Data
      • Home Property Listings
      • Custom Not Found & Loading Pages
  • Git and GitHubs
    • Git Installation
    • Git Commands
    • GitHub Repository
    • Hands-on Practice
  • Database in Application
    • React Supabase CRUD
    • Hands-on: Note Taking App
  • NoSQL Database
    • Installing MongoDB Community Edition
    • System Env Path Setting
    • How to use MongoDB Shell
    • How to Connect and Use Mongosh in VS Code via MongoDB Extension
    • MongoDB Guide
  • Solo Project 2
  • Deployment and Web Hosting
    • Lesson 1. React+Vite+TS+Shadcn Project
    • Lesson 2. Deploying a React Vite App to Vercel from Vercel CLI
    • Lesson 3 Connecting to GitHub Repo and Automate Deployment
  • Solo Project 3
  • Final Term Project
    • Level 1 Team Project
    • Level 1 Team Project
    • Level 1 Team Project
    • Level 1 Team Project
    • Level 2 Team Project
    • Level 2 Team Project
    • Level 3 Team Project
    • Level 3 Team Project
Powered by GitBook
On this page
  • Creating BookList.jsx Component
  • Explanation of BookList.jsx Code Structure
  • Key Takeaways for Students:
  • Challenge :
  1. RESTful APIs :Build a BookSearch App -Ver 2.0

Lesson 5 - Create BookList.jsx Component

Creating BookList.jsx Component

Next, write a React child component code named "BookList.jsx" to display book contents with fetched data and query.

Layout Structure

// Layout Design of BookList Component
BookList Component
│
├── Props
│   ├── books (array) - Collection of book objects
│   └── query (string) - Current search query
│
└── Render Structure
    └── <div> (mt-4)
        ├── <h3> (text-center) - "Book Search Results for '{query}'"
        │
        └── Conditional Rendering
            ├── IF books.length > 0
            │   └── <div> (row)
            │       └── books.map() - Iterates through each book
            │           └── <div> (col-md-4 mb-4) - For each book
            │               └── <div> (card h-100)
            │                   └── <div> (card-body)
            │                       ├── <h5> (card-title) - Book title
            │                       │
            │                       ├── <p> (card-text) - Authors
            │                       │   ├── <strong>Authors:</strong>
            │                       │   └── Conditional: authors.join(', ') OR 'Unknown'
            │                       │
            │                       ├── <p> (card-text) - Description
            │                       │   ├── <strong>Description:</strong>
            │                       │   └── Conditional: truncated description OR 'No Description Available'
            │                       │
            │                       └── <p> (card-text) - Publisher
            │                           ├── <strong>Publisher:</strong>
            │                           └── Conditional: publisher OR 'Unknown'
            │
            └── ELSE
                └── <p> (text-center) - "No books found for '{query}'"
// BookList.jsx
// Import necessary libraries
import React from 'react';
import PropTypes from 'prop-types';

const BookList = ({ books, query }) => {
  return (
    <div className="mt-4">
      {/* Heading to show the current search query */}
      <h3 className="text-center">Book Search Results for "{query}"</h3>

      {/* Check if books are available */}
      {books.length > 0 ? (
        <div className="row">
          {books.map((book) => (
            <div key={book.id} className="col-md-4 mb-4">
              <div className="card h-100">
                <div className="card-body">
                  {/* Display book title */}
                  <h5 className="card-title">{book.volumeInfo.title || 'No Title Available'}</h5>

                  {/* Display book authors */}
                  <p className="card-text">
                    <strong>Authors:</strong>{' '}
                    {book.volumeInfo.authors ? book.volumeInfo.authors.join(', ') : 'Unknown'}
                  </p>

                  {/* Display book description */}
                  <p className="card-text">
                    <strong>Description:</strong>{' '}
                    {book.volumeInfo.description
                      ? book.volumeInfo.description.substring(0, 100) + '...'
                      : ('No Description Available')}
                  </p>
                  

                  {/* Display book publisher */}
                  <p className="card-text">
                    <strong>Publisher:</strong>{' '}
                    {book.volumeInfo.publisher || 'Unknown'}
                  </p>
                </div>
              </div>
            </div>
          ))}
        </div>
      ) : (
        <p className="text-center">No books found for "{query}"</p>
      )}
    </div>
  );
};

// Define PropTypes for the component
BookList.propTypes = {
  books: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.string.isRequired,
      volumeInfo: PropTypes.shape({
        title: PropTypes.string,
        authors: PropTypes.arrayOf(PropTypes.string),
        description: PropTypes.string,
        publisher: PropTypes.string,
      }).isRequired,
    })
  ).isRequired,
  query: PropTypes.string.isRequired,
};

export default BookList;

Explanation of BookList.jsx Code Structure

The BookList component is designed to display a list of books fetched from the API along with the query used. Here's the step-by-step explanation:


1. Importing Libraries

import React from 'react';
import PropTypes from 'prop-types';
  • React: Core library for creating React components.

  • PropTypes: Ensures the props passed to the component are valid and well-defined.

  • Bootstrap: Provides styling for the layout and components.


2. Component Declaration

const BookList = ({ books, query }) => {
  • Props:

    • books: An array of book objects fetched from the API.

    • query: The current search term entered by the user.


3. Display Book Query Search Results

<h3 className="text-center">Results for "{query}"</h3>
  • Purpose:

    • Displays the current search query to inform the user of the context.


4. Conditional Rendering

{books.length > 0 ? (
  // Render book cards if books are available
) : (
  <p className="text-center">No books found for "{query}"</p>
)}
  • If books exist:

    • Render a list of book cards dynamically using map.

  • If no books are found:

    • Show a user-friendly message.


5. Rendering Book Information

<div className="row">
  {books.map((book) => (
    <div key={book.id} className="col-md-4 mb-4">
      <div className="card h-100">
        <div className="card-body">
          <h5 className="card-title">{book.volumeInfo.title || 'No Title Available'}</h5>
          <p className="card-text"><strong>Authors:</strong> {book.volumeInfo.authors ? book.volumeInfo.authors.join(', ') : 'Unknown'}</p>
          <p className="card-text"><strong>Description:</strong> {book.volumeInfo.description ? book.volumeInfo.description.substring(0, 100) + '...' : 'No Description Available'}</p>
          <p className="card-text"><strong>Publisher:</strong> {book.volumeInfo.publisher || 'Unknown'}</p>
        </div>
      </div>
    </div>
  ))}
</div>
  • map Function:

    • Iterates over the books array to dynamically generate a Bootstrap card for each book.

  • Book Details:

    • Title: Displays the book's title or a fallback message.

    • Authors: Joins the list of authors or displays "Unknown".

    • Description: Shows the first 100 characters of the description with a fallback.

    • Publisher: Displays the publisher or "Unknown".

    • Search Result Style: modify

      col-md-6

6. Prop Validation

BookList.propTypes = {
  books: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.string.isRequired,
      volumeInfo: PropTypes.shape({
        title: PropTypes.string,
        authors: PropTypes.arrayOf(PropTypes.string),
        description: PropTypes.string,
        publisher: PropTypes.string,
      }).isRequired,
    })
  ).isRequired,
  query: PropTypes.string.isRequired,
};
  • Purpose:

    • Validates the structure and types of books and query props to prevent runtime errors.

  • Details:

    • books is an array of objects with a defined structure.

    • query is a string and must be provided.


7. Exporting the Component

export default BookList;
  • Purpose:

    • Makes the BookList component reusable in other parts of the app.


Key Takeaways for Students:

  1. Dynamic Rendering:

    • Use the map function to generate a list of items dynamically.

    • Handle missing or undefined data gracefully with fallback values.

  2. Conditional Logic:

    • Use conditional rendering to display appropriate content when data is unavailable.

  3. Prop Validation:

    • Use PropTypes to ensure data passed to components meets the expected format.

  4. Styling with Bootstrap:

    • Quickly style components using Bootstrap classes for layout and spacing.

This component is ready to integrate into the parent AppBookShelf.jsx. Let me know if you need further explanation or want to proceed with the next child component!

Challenge :

  • Add "Read More" button to get the full description about the book when clicked by creating a new component "ReadMore.jsx"

  • Implement a react child component named "ReadMore.jsx" to show the full description of the book selected when clicked "Read More" button and when clicked "Close" button, go back to the previous state.

// Code Snippet in BookList.jsx
{/* Display book description */}
                  <p className="card-text">
                    <strong>Description:</strong>{' '}
                    {book.volumeInfo.description ? (
                      <ReadMore text={book.volumeInfo.description} />
                    ) : (
                      'No Description Available'
                    )}
                  </p>
  • ReadMore Component

// Components/ReadMore.jsx
// Import necessary libraries
import React, { useState } from 'react'
import PropTypes from 'prop-types'

const ReadMore = ({ text }) => {
  const [isExpanded, setIsExpanded] = useState(false)

  // Toggle the expanded state
  const toggleExpanded = () => {
    setIsExpanded(!isExpanded)
  }

  return (
    <div>
      {isExpanded ? (
        <>
          <p>{text}</p>
          <button className="btn btn-secondary btn-sm" onClick={toggleExpanded}>
            Close
          </button>
        </>
      ) : (
        <>
          <p>{text.length > 100 ? `${text.substring(0, 100)}...` : text}</p>
          {text.length > 100 && (
            <button className="btn btn-primary btn-sm" onClick={toggleExpanded}>
              Read More
            </button>
          )}
        </>
      )}
    </div>
  )
}

// Define PropTypes for the component
ReadMore.propTypes = {
  text: PropTypes.string.isRequired,
}

export default ReadMore
PreviousLesson 4 - Create Footer ComponentNextLesson 6 - Create BookCard.jsx Component

Last updated 20 days ago