Shopkart Pagination and Sorting

Business Scenario

Hello talented developers!

In the previous lab, Lab 8 — ShopKart Product Details & Dynamic Routing, you enhanced the ShopKart application by allowing users to navigate from the Product Page to individual Product Details pages. Users could view detailed product information, specifications, reviews, select quantities, and add products to the cart.

As the ShopKart product catalog grows, displaying a large number of products on a single page can make it difficult for users to find and compare products. To improve product discovery and navigation, Lab 9 will enhance the existing Product Page by introducing sorting and pagination.

In this lab, students will implement sorting options that allow users to organize products based on criteria such as price, rating, and popularity.

Pagination will divide the products into multiple pages and display only a specific number of products on each page.

Next-Lab Preparation

Module:

1) useState , Array Methods
2) Event handling , Conditional Rendering, List Rendering

git pull origin branchName

Git Pull

Task 1 : Add Sorting Functionality

Create Sorting State

1

const [sortOption, setSortOption] = useState("");
  • Open: Add useState if it is not already imported and inside the Products component, add

Add the Sort Dropdown

2

<div className="sort-section">
  
  <label htmlFor="sort">Sort By:</label>

  <select id="sort" value={sortOption} onChange={(e) => setSortOption(e.target.value)}>
    <option value="">Default</option>
    <option value="price-low">Price: Low to High</option>
    <option value="price-high">Price: High to Low</option>
    <option value="rating-high">Rating: High to Low</option>
    <option value="rating-low">Rating: Low to High</option>
    <option value="popular">Most Popular</option>
  </select>
  
</div>
  • Create a dropdown that allows users to select how products should be sorted. The dropdown will provide options for price, rating, and popularity.

Create a Copy of Filtered Products

3

  • Before sorting the products, create a copy of the filtered product list. This prevents the original product array from being directly modified by sort().
  • After your existing filteredProducts logic, add:
let sortedProducts = [...filteredProducts];

Implement Price Sorting

4

  • Use JavaScript's sort() method to arrange products according to their price.
if (sortOption === "price-low") {
  sortedProducts.sort(
    (a, b) =>
      Number(String(a.price).replace(/,/g, "")) -
      Number(String(b.price).replace(/,/g, ""))
  );
}


if (sortOption === "price-high") {
  sortedProducts.sort(
    (a, b) =>
      Number(String(b.price).replace(/,/g, "")) -
      Number(String(a.price).replace(/,/g, ""))
  );
}
  • if (sortOption === "price-low") { --> Checks whether the user selected Price: Low to High or Price: High to Low.
  • .sort((a, b) => ...) compares two products at a time.
  • String() and .replace() remove commas from prices like "12,499".
  • Number() converts the price into a number for proper comparison.
  • a - b sorts low to high, while b - a sorts high to low.

Implement Rating Sorting

5

  • Allow users to arrange products according to their customer rating.
if (sortOption === "rating-high") {
  sortedProducts.sort( (a, b) => b.rating - a.rating );
}

if (sortOption === "rating-low") {
  sortedProducts.sort( (a, b) => a.rating - b.rating );
}

Implement Rating Sorting

6

  • Use the number of reviews as the popularity indicator. Products with more reviews will be considered more popular and will appear first.
if (sortOption === "popular") {
  sortedProducts.sort(
    (a, b) => b.reviews - a.reviews
  );
}

Display the Sorted List

7

  • Replace the existing filteredProducts.map() with sortedProducts.map() so the Product Page displays the products according to the selected sorting option.
filteredProducts.map((product) => (
  • Change :
sortedProducts.map((product) => (
  • To :
sortedProducts.length > 0
  • Also change the condition to :

Style the Sort drop-down

8

Task 2 :  Add Pagination

Create Pagination State

1

  • Create state variables to keep track of the current page and the number of products displayed on each page.
const [currentPage, setCurrentPage] = useState(1);
const productsPerPage = 8;

Calculate the Total Number of Pages

2

  • Calculate how many pages are required based on the number of sorted products
const totalPages = Math.ceil( sortedProducts.length / productsPerPage);
  • Add after the sorting logic:
  • For example, if there are 12 products and 8 products are displayed per page:

12 products ÷ 8 products per page = 2 pages

  • sortedProducts.length --> Gives the total number of products after sorting.
  • productsPerPage --> Stores how many products we want to show on each page.
  • Math.ceil() rounds a number up to the next whole number.
  • Division : 12 / 8 = 1.5 --> This means we need 1.5 pages, but we cannot have half a page.

Calculate the Total Number of Pages

3

  • Use the slice() array method to display only the products belonging to the selected page.
const startIndex = (currentPage - 1) * productsPerPage;
const endIndex = startIndex + productsPerPage;
const currentProducts = sortedProducts.slice(startIndex, endIndex);
  • startIndex finds where the current page's products should start. For example, Page 1 → (1 - 1) × 8 = 0, so it starts at index 0.
  • endIndex finds where the current page's products should end. For Page 1 → 0 + 8 = 8.
  • slice(startIndex, endIndex) takes only that portion of the product list. So Page 1 gets products at indexes 0–7, and Page 2 gets indexes 8–11.

Page 1 → indexes 0 – 7  → 8 products
Page 2 → indexes 8 – 15 → 8 products
Page 3 → indexes 16 – 23 → 8 products

For example :

Display Current Page Products

4

  • The Product Grid should now render only the products belonging to the current page instead of displaying the complete sorted list.
sortedProducts.map((product) => (
  • Change :
currentProducts.map((product) => (
  • To :

But note one thing...

  • We will keep the condition as  : sortedProducts.length > 0
  • Because sortedProducts represents the complete product list after filtering and sorting. Pagination only determines which products from this list are displayed on the current page.

Create Pagination Buttons

5

  • Create navigation controls that allow users to move between product pages.
  • Add this below the product grid:
{totalPages > 1 && (
  <div className="pagination">
    <button onClick={() => setCurrentPage((previous) => Math.max(previous - 1, 1))} 
     disabled={currentPage === 1}> ← </button>
    {Array.from({ length: totalPages }, (_, index) => (
      <button key={index + 1} className={currentPage === index + 1 ? "active" : ""} 
      onClick={() => setCurrentPage(index + 1)}>
        {index + 1}
      </button>
    ))}

    
    <button onClick={() => setCurrentPage((previous) =>
      Math.min(previous + 1, totalPages))} 
    disabled={currentPage === totalPages}>
      →
    </button>

  </div>
)}
  • This dynamically creates the page numbers.

For 16 products:

←  1  2  3  →

Reset Pagination When Sorting Changes

6

  • When users change the sorting option, they should automatically return to the first page. This prevents situations where the selected page no longer contains products after the list order changes.
useEffect(() => {setCurrentPage(1);}, [sortOption]);

Reset Pagination When Filters Change

7

  • When a filter is changed, the number of available products may change. Therefore, the Product Page should return to page 1 whenever the filtering state changes.
 useEffect(() => {setCurrentPage(1);}, [selectedCategories,maxPrice,selectedRating,availability]);

This means whenever any of these filters changes:

  • selectedCategories
  • maxPrice
  • selectedRating
  • availability

Style the Pagination buttons

8

We are done with this lab. The latest source code has been uploaded to GitHub. You can access the latest commit using the link below: 

 

Great job!

You successfully implemented dynamic product details, routing, cart actions, and a 404 page in ShopKart.

Checkpoint

   Git Push

git push origin branchName

Next-Lab Preparation

Module:

1) useState , Array Methods
2) Event handling , Conditional Rendering, List Rendering

React lab 9

By Content ITV

React lab 9

  • 43