'How to handle "Loader" and "No result found" message when filtering data in React?

I am using React and Firebase to build an ecommerce, I just want to set the Loader at the right time and the "No result found" message when I'm filtering the data through input search and the searchKey is not matching any product.

So the target is: handle both the situations and never show an empty page when there is no result after a search by input field.

The category filter is working properly, but if you suggest any change you're welcome.

I was trying to make a separate function for each search, but at the moment I'm handling the setState functions directly in the JSX (as you can see in the HomePage component). Still, if you think that is better to separate the logic from the JSX, you're welcome.

I know is a very basic problem to solve, but it always confuse me. If you can help me it would be awesome guys.

This is the getProducts() function to retrieve products from firebase/firestore

import { collection, getDocs, getDoc, doc } from "firebase/firestore";
import DB from '../../firebase';

const getProducts = async (setProducts) => {

    try {
        const productsFromFB = await getDocs(collection(DB, 'products'))
        let productsContainer = []
        productsFromFB.forEach(doc => {
            const productWithID = {
                id: doc.id,
                ...doc.data()
            }
            productsContainer.push(productWithID)
        })
        setProducts(productsContainer)

    } catch (error) {
        console.log(error)
    }
}

HomePage component, where there's the issue

// React stuff
import React, { useState, useEffect } from 'react'

// components
import { Layout, Product, Loader, FilterInputs } from '../components/components-provider/components-provider'

// functions
import { getProducts } from './pages-provider/pages-functions'

const HomePage = () => {

    const [products, setProducts] = useState([])
    const [searchKey, setSearchKey] = useState("")
    const [category, setCategory] = useState("")

    useEffect(() => {
        getProducts(setProducts)
    }, [])

    return (
        <Layout>
            <div className="container">
                <div className="row">
                    <FilterInputs
                        searchKey={searchKey}
                        category={category}
                        setSearchKey={setSearchKey}
                        setCategory={setCategory}
                     />

/// HERE I NEED TO HANDLE BOTH LOADER AND NO RESULTS FOUND
                    {products.length > 0 ? products
                        .filter(toFilterItem => toFilterItem.name.toLowerCase().includes(searchKey))
                        .filter(toFilterCategory => toFilterCategory.category.toLowerCase().includes(category))
                        .map(product => (
                            <Product product={product} key={product.id} />
                        )) : <Loader />}
                </div>
            </div>
        </Layout>
    )
}

export default HomePage

FilterInputs component

import React from 'react'

const FilterInputs = (props) => {
    return (
        <div className="d-flex">
            <input
                type="text"
                value={props.searchKey}
                onChange={(e) => props.setSearchKey(e.target.value)}
                className="form-control"
                placeholder="Search Items..." />

            <select
                onChange={(e) => props.setCategory(e.target.value)}
                value={props.category}
                className="form-control">
                <option value="">All</option>
                <option value="home">Home</option>
                <option value="food">Food</option>
                <option value="electronics">Electronics</option>
            </select>
        </div>
    )
}

export default FilterInputs


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source