React Grid View API Products with Search Filter – Step-by-Step Guide

Learn how to use React grid view API products with a real-time search filter. Follow this step-by-step guide to build a clean, responsive UI.


🔧 1. Create the React App

npx create-react-app product-api-app
cd product-api-app


📦 2. Install Bootstrap

npm install bootstrap

And import Bootstrap in src/index.js:

import 'bootstrap/dist/css/bootstrap.min.css';


📁 3. Create Components

👉 Create Product.js

// src/Product.js
function Product({ product }) {
    return (
        <div className="col-md-4 col-sm-6 mb-4 d-flex">
            <div className="card h-100 shadow-sm">
                <img
                    className="card-img-top object-fit-contain"
                    style={{ height: '200px' }}
                    src={product.image}
                    alt={`Image of ${product.title}`}
                />
                <div className="card-body d-flex flex-column">
                    <h5 className="card-title">{product.title}</h5>
                    <p><strong>Category:</strong> {product.category}</p>
                    <p><strong>Price:</strong> ${product.price}</p>
                    <p>{product.description.slice(0, 80)}...</p>
                    <p>⭐️{product.rating.rate} ({product.rating.count} reviews)</p>
                    <div className="mt-auto">
                        <button
                            className="btn btn-outline-info w-100"
                            onClick={() => alert(`Thanks for buying: ${product.title}`)}
                        >
                            Buy Now
                        </button>
                    </div>
                </div>
            </div>
        </div>
    );
}

export default Product;

👉 Create ApiProductList.js

// src/ApiProductList.js
import { useState, useEffect } from "react";
import Product from "./Product";

function ApiProductList() {
    const [products, setProductList] = useState([]);
    const [loading, setLoading] = useState(true);
    const [searchText, setSearchText] = useState('');

    useEffect(() => {
        fetch('https://fakestoreapi.com/products')
            .then((res) => res.json())
            .then((data) => {
                setProductList(data);
                setLoading(false);
            }).catch((err) => {
                console.error("Failed to fetch:", err);
            });
    }, []);

    const filtered = products.filter(p =>
        p.title.toLowerCase().includes(searchText.toLowerCase()) ||
        p.category.toLowerCase().includes(searchText.toLowerCase())
    );

    return (
        <div className="container">
            <h1 className="text-info text-center">Product List from API</h1><hr />
            <input
                type="text"
                className="form-control mb-4"
                placeholder="Search by product name or category..."
                value={searchText}
                onChange={(e) => setSearchText(e.target.value)}
            />
            {loading ? (
                <p>Loading...</p>
            ) : (
                <div className="row">
                    {filtered.map(product => (
                        <Product key={product.id} product={product} />
                    ))}
                </div>
            )}
        </div>
    );
}

export default ApiProductList;

🔁 4. Update App.js

// src/App.js
import ApiProductList from "./ApiProductList";

function App() {
  return (
    <div>
      <ApiProductList />
    </div>
  );
}

export default App;


▶️ 5. Run Your App

npm start
Screenshot of product listing grid with search filter input applied
Filtered product grid view displaying matching items based on search text
Screenshot of product listing grid with search filter input applied
Filtered product grid view displaying matching items based on search text