<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Agunrege Oyinkan</title>
    <description>The latest articles on DEV Community by Agunrege Oyinkan (@zhullyblog).</description>
    <link>https://dev.to/zhullyblog</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2581633%2F37bb6f3d-5279-4e41-be8c-5e8eadcf5af8.png</url>
      <title>DEV Community: Agunrege Oyinkan</title>
      <link>https://dev.to/zhullyblog</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zhullyblog"/>
    <language>en</language>
    <item>
      <title>Create a Powerful E-commerce Search and Filtering System with React</title>
      <dc:creator>Agunrege Oyinkan</dc:creator>
      <pubDate>Wed, 18 Dec 2024 12:46:02 +0000</pubDate>
      <link>https://dev.to/zhullyblog/create-a-powerful-e-commerce-search-and-filtering-system-with-react-34gg</link>
      <guid>https://dev.to/zhullyblog/create-a-powerful-e-commerce-search-and-filtering-system-with-react-34gg</guid>
      <description>&lt;p&gt;When building an ecommerce website, developers are often presented with extensive list of items/products. But as a developer, you need to ensure that users are able to items swiftly without having to navigate through extensive list. As developers, integrating search input for real-time filtering and enabling users locate product by categories or prices will make users get a better shopping experience on our E-commerce website. While building a &lt;a href="https://youtu.be/wbmlprlD5Qg" rel="noopener noreferrer"&gt;Full Stack Ecommerce Website&lt;/a&gt; using MERN Stack and i decided to make a Powerful Search and Filter Website&lt;/p&gt;

&lt;p&gt;Here's a visual representation of what you are going to build&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61fsrf0gclgicbc85ngc.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61fsrf0gclgicbc85ngc.jpeg" alt="Image description" width="800" height="885"&gt;&lt;/a&gt;&lt;br&gt;
In this tutorial, we will learn to build a powerful filtering system in React. You'll learn how to:&lt;/p&gt;

&lt;p&gt;Filter by Category: Allow users to narrow down items based on specific categories.&lt;/p&gt;

&lt;p&gt;Filter by Size: Enable filtering of products by size attributes.&lt;/p&gt;

&lt;p&gt;Sort by Price: Implement sorting functionality to arrange items from high to low prices and vice versa.&lt;/p&gt;

&lt;p&gt;Search Filter: Integrate a search bar for real-time filtering based on user input.&lt;/p&gt;

&lt;p&gt;Here's a visual representation of what you are going to build&lt;/p&gt;

&lt;p&gt;Let's dive into the actual development.&lt;/p&gt;

&lt;p&gt;Ensure you have basic react knowledge to implement this properly.&lt;/p&gt;

&lt;p&gt;This is the code structure.&lt;/p&gt;

&lt;p&gt;Navbar.jsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, {useContext, useState} from 'react'
import {BiUser, BiCart} from 'react-icons/bi'
import './Navbar.css'
import { ShopContext } from '../context/ShopContext'


const Navbar = () =&amp;gt; {

    const { updateSearchTerm } = useContext(ShopContext)

    const [searchInput, setSearchInput] = useState('')


    const handleSearch = () =&amp;gt; {
        updateSearchTerm(searchInput);
    }

  return (
    &amp;lt;div&amp;gt;
        &amp;lt;nav className="navbar"&amp;gt;
            &amp;lt;div className="nav-top"&amp;gt;
                &amp;lt;h2&amp;gt;Luma&amp;lt;/h2&amp;gt;
                &amp;lt;div className="search-bar"&amp;gt;
                    &amp;lt;input type="text" value={searchInput} onChange={(e) =&amp;gt; setSearchInput(e.target.value)} className='search-input' placeholder='Search for products....' /&amp;gt;
                    &amp;lt;button onClick={handleSearch} className="search-btn"&amp;gt;Search&amp;lt;/button&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div className="icons"&amp;gt;
                    &amp;lt;div className="profile-group"&amp;gt;
                        &amp;lt;BiUser className='icon'/&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div className="cart-icon"&amp;gt;
                        &amp;lt;BiCart className='icon' /&amp;gt;
                        &amp;lt;span className="cart-count"&amp;gt;0&amp;lt;/span&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/nav&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default Navbar

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ProductFilter.jsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, {useState, useEffect, useContext} from 'react'
import { ShopContext } from '../context/ShopContext';

import './ProductFilter.css'

const ProductFilter = () =&amp;gt; {

    const {products, searchTerm } = useContext(ShopContext);
    const [displayFilter, setDisplayFilter] = useState(false);
    const [filteredProduct, setFilteredProduct] =useState([]);
    const [category, setCategory] = useState([]);
    const [sizeCategory, setSizeCategory] = useState([]);
    const [material, setMaterialCategory] = useState([]);
    const [sortType, setSortType] = useState('relevant');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  // Function to toggle the selected categories in the filter
  const toggleCategory = (e) =&amp;gt; {
    // Check if the clicked category is already selected
    if (category.includes(e.target.value)) {
      // If the category is selected, remove it from the selected categories array
      setCategory(prev =&amp;gt; prev.filter(item =&amp;gt; item !== e.target.value));
    } else {
      // If the category is not selected, add it to the selected categories array
      setCategory(prev =&amp;gt; [...prev, e.target.value]);
    }
  };

  // Function to toggle the selected sizecategories in the filter
  const togglesizeCategory = (e) =&amp;gt; {
    // Check if the clicked sizecategory is already selected
    if (sizeCategory.includes(e.target.value)) {
      // If the sizecategory is selected, remove it from the selected sizecategories array
      setSizeCategory(prev =&amp;gt; prev.filter(item =&amp;gt; item !== e.target.value));
    } else {
      // If the sizecategory is not selected, add it to the selected sizecategories array
      setSizeCategory(prev =&amp;gt; [...prev, e.target.value]);
    }
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Function to toggle the selected sizecategories in the filter
   const toggleMaterialCategory = (e) =&amp;gt; {
    // Check if the clicked sizecategory is already selected
    if (material.includes(e.target.value)) {
      // If the sizecategory is selected, remove it from the selected material array
      setMaterialCategory(prev =&amp;gt; prev.filter(item =&amp;gt; item !== e.target.value));
    } else {
      // If the Materialcategory is not selected, add it to the selected Materialcategories array
      setMaterialCategory(prev =&amp;gt; [...prev, e.target.value]);
    }
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  // Function to apply filters on the product list based on category, sizecategory, and search criteria
  const filterResults = () =&amp;gt; {
    // Create a copy of the original products array to avoid mutating the original data
    let duplicateProduct = products.slice();

    // If search is enabled (showSearch is true) and there's a search term
    if (searchTerm) {
      // Filter products by checking if the product name includes the search term (case-insensitive)
      duplicateProduct = duplicateProduct.filter(item =&amp;gt;
        item.name.toLowerCase().includes(searchTerm.toLowerCase())
      );
    }

    // If there are selected categories, filter products to include only those categories
    if (category.length &amp;gt; 0) {
      duplicateProduct = duplicateProduct.filter(item =&amp;gt; category.includes(item.category));
    }

    // If there are selected sizecategories, filter products to include only those sizecategories
    if (sizeCategory.length &amp;gt; 0) {
      duplicateProduct = duplicateProduct.filter(item =&amp;gt; sizeCategory.includes(item.sizeCategory));
    }

    // If there are selected sizecategories, filter products to include only those sizecategories
    if (material.length &amp;gt; 0) {
      duplicateProduct = duplicateProduct.filter(item =&amp;gt; material.includes(item.material));
    }

    // Update the filtered product list state with the filtered products
    setFilteredProduct(duplicateProduct);
  };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // Function to sort the filtered product list based on the selected sorting type
  const sortProduct = () =&amp;gt; {
    // Create a copy of the filtered products to avoid mutating the state directly
    let fpCopy = filteredProduct.slice();

    // Sort products based on the sorting type
    switch (sortType) {
      case 'low-high':
        // Sort by price in ascending order
        setFilteredProduct(fpCopy.sort((a, b) =&amp;gt; a.price - b.price));
        break;

      case 'high-low':
        // Sort by price in descending order
        setFilteredProduct(fpCopy.sort((a, b) =&amp;gt; b.price - a.price));
        break;

      default:
        // If no sort type is selected, reapply the filters
        filterResults();
        break;
    }
  };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  // useEffect to reapply filters whenever any of the dependencies (category, sizeCategory, search, etc.) change
  useEffect(() =&amp;gt; {
    filterResults();
  }, [category, sizeCategory,material, searchTerm, products]);

  // useEffect to sort the filtered products whenever the sorting type changes
  useEffect(() =&amp;gt; {
    sortProduct();
  }, [sortType]);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
    &amp;lt;&amp;gt;
    &amp;lt;div className="filter-and-products-container"&amp;gt;
      {/* Filter Option */}
      &amp;lt;div className="filter-container"&amp;gt;
        &amp;lt;p 
          onClick={() =&amp;gt; setDisplayFilter(!displayFilter)} 
          className="filter-title"
        &amp;gt;
          FILTERS
        &amp;lt;/p&amp;gt;
        {/* Category Filter */}
        &amp;lt;div className={`filter-section ${displayFilter ? '' : 'hidden'}`}&amp;gt;
        &amp;lt;p className="filter-sizetitle"&amp;gt;GENDER&amp;lt;/p&amp;gt;
          &amp;lt;p className="filter-item"&amp;gt;
            &amp;lt;input type="checkbox" onChange={toggleCategory} value="Men" /&amp;gt; Men
          &amp;lt;/p&amp;gt;
          &amp;lt;p className="filter-item"&amp;gt;
            &amp;lt;input type="checkbox" onChange={toggleCategory} value="Women" /&amp;gt; Women
          &amp;lt;/p&amp;gt;
          &amp;lt;p className="filter-item"&amp;gt;
            &amp;lt;input type="checkbox" onChange={toggleCategory} value="Kids" /&amp;gt; Kids
          &amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
        {/* sizecategory Filter */}
        &amp;lt;div className={`filter-section ${displayFilter ? '' : 'hidden'}`}&amp;gt;
          &amp;lt;p className="filter-sizetitle"&amp;gt;CLOTHING SIZE&amp;lt;/p&amp;gt;
          &amp;lt;div className="filter-sizecategory"&amp;gt;
            &amp;lt;p className="filter-item"&amp;gt;
              &amp;lt;input type="checkbox" onChange={togglesizeCategory} value="Juniors" /&amp;gt; Juniors
            &amp;lt;/p&amp;gt;
            &amp;lt;p className="filter-item"&amp;gt;
              &amp;lt;input type="checkbox" onChange={togglesizeCategory} value="Petite" /&amp;gt; Petite
            &amp;lt;/p&amp;gt;
            &amp;lt;p className="filter-item"&amp;gt;
              &amp;lt;input type="checkbox" onChange={togglesizeCategory} value="Plussize" /&amp;gt; Plus Size
            &amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; {/* Material filter */}
        &amp;lt;div className={`filter-section ${displayFilter ? '' : 'hidden'}`}&amp;gt;
          &amp;lt;p className="filter-sizetitle"&amp;gt;MATERIAL&amp;lt;/p&amp;gt;
          &amp;lt;div className="filter-sizecategory"&amp;gt;
            &amp;lt;p className="filter-item"&amp;gt;
              &amp;lt;input type="checkbox" onChange={toggleMaterialCategory} value="Cotton" /&amp;gt; Cotton
            &amp;lt;/p&amp;gt;
            &amp;lt;p className="filter-item"&amp;gt;
              &amp;lt;input type="checkbox" onChange={toggleMaterialCategory} value="Leather" /&amp;gt; Leather
            &amp;lt;/p&amp;gt;
            &amp;lt;p className="filter-item"&amp;gt;
              &amp;lt;input type="checkbox" onChange={toggleMaterialCategory} value="Silk" /&amp;gt; Silk
            &amp;lt;/p&amp;gt;
            &amp;lt;p className="filter-item"&amp;gt;
              &amp;lt;input type="checkbox" onChange={toggleMaterialCategory} value="Suede" /&amp;gt; Suede
            &amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  {/* Right Side */}
      &amp;lt;div className="products-container"&amp;gt;
        &amp;lt;div className="products-header"&amp;gt;
          &amp;lt;h2&amp;gt;All Collection&amp;lt;/h2&amp;gt;
          &amp;lt;select 
            onChange={(e) =&amp;gt; setSortType(e.target.value)} 
            className="sort-dropdown"
          &amp;gt;
            &amp;lt;option value="relevant"&amp;gt;Sort by: Relevant&amp;lt;/option&amp;gt;
            &amp;lt;option value="low-high"&amp;gt;Sort by: Low to High&amp;lt;/option&amp;gt;
            &amp;lt;option value="high-low"&amp;gt;Sort by: High to Low&amp;lt;/option&amp;gt;
          &amp;lt;/select&amp;gt;
        &amp;lt;/div&amp;gt;
        {/* Map Products */}
        &amp;lt;div className="product-grid"&amp;gt;
          {filteredProduct.map((product) =&amp;gt; (
            &amp;lt;div className="product-card" key={product._id}&amp;gt;
              &amp;lt;div className="product-image"&amp;gt;
                &amp;lt;img src={product.image[0]} alt={product.name} /&amp;gt;
              &amp;lt;/div&amp;gt;
              &amp;lt;h3&amp;gt;{product.name}&amp;lt;/h3&amp;gt;
              &amp;lt;p&amp;gt;${product.price}&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
          ))}
        &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

export default ProductFilter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ShoContext.jsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Import necessary functions and data from React and local assets
import { createContext, useState } from "react";
import { product } from '../assets/assets'

// Create a new context named ShopContext
export const ShopContext = createContext()

// Define the ShopContextProvider component that will wrap child components
const ShopContextProvider = ({ children }) =&amp;gt; {

    // Initialize the products state with data imported from assets
    const [products, setProducts] = useState(product)

    // Initialize the searchTerm state to manage the search input
    const [searchTerm, setSearchTerm] = useState('')

    // Function to update the searchTerm state
    const updateSearchTerm = (term) =&amp;gt; {
        setSearchTerm(term)
    }

    // Define the value object containing state and updater function
    const value = {
        products,        // Current list of products
        searchTerm,     // Current search term
        updateSearchTerm // Function to update the search term
    }

    // Return the context provider wrapping the child components
    return (
        &amp;lt;ShopContext.Provider value={value}&amp;gt;
            {children}
        &amp;lt;/ShopContext.Provider&amp;gt;
    )
}

// Export the ShopContextProvider component as the default export
export default ShopContextProvider;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a video tutorial, &lt;a href="https://youtu.be/v_MWqw3a7VU" rel="noopener noreferrer"&gt;check this video&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
