0:00
/
0:00
Transcript

🔍 Implement Search & Category Filtering in React with TailwindCSS (2025 Guide)

In this guide, you’ll learn how to implement powerful search and category filtering in a React application using TailwindCSS for styling. This builds on a previous project where we created a responsive recipe website.

By the end of this tutorial, you'll be able to:

  • Filter recipe cards by text input

  • Filter by category dropdown

  • Clear search with a single click

  • Ensure case-insensitive matching


✅ Prerequisites

  • A React app already set up (ideally with TailwindCSS + recipe data)

  • Basic understanding of React state and hooks


🧱 Step 1: Create State for Search and Category

Inside your RecipesPage.jsx (or App.jsx if everything is in one file):

const [searchQuery, setSearchQuery] = useState("");
const [category, setCategory] = useState("");
const [filteredRecipes, setFilteredRecipes] = useState(recipes);

🎨 Step 2: Create the UI

🔍 Search + Filter Inputs

<div className="container mx-auto mt-8">
  <h2 className="text-3xl font-bold mb-8 text-center text-gray-800">Featured Recipes</h2>

  <div className="flex flex-col md:flex-row justify-center mb-6 space-y-4 md:space-y-0 md:space-x-4">
    <input
      type="text"
      placeholder="Search for recipes..."
      value={searchQuery}
      onChange={(e) => setSearchQuery(e.target.value)}
      className="w-full md:w-1/2 px-4 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-amber-500"
    />

    <select
      value={category}
      onChange={(e) => setCategory(e.target.value)}
      className="w-full md:w-1/4 px-4 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-amber-500"
    >
      <option>All Categories</option>
      {[...new Set(recipes.map(recipe => recipe.category))].map((cat, i) => (
        <option key={i} value={cat}>{cat}</option>
      ))}
    </select>

    <button
      onClick={() => {
        setSearchQuery("");
        setCategory("");
      }}
      className="cursor-pointer bg-gradient-to-r from-amber-500 to-orange-500 hover:from-orange-500 hover:to-amber-500 text-white px-6 py-2 rounded transition duration-300"
    >
      Clear Search
    </button>
  </div>
</div>

⚙️ Step 3: Search Logic with useEffect

useEffect(() => {
  const query = searchQuery.toLowerCase();

  const result = recipes.filter(recipe =>
    recipe.title.toLowerCase().includes(query) ||
    recipe.ingredients.some(ing => ing.toLowerCase().includes(query)) ||
    recipe.category.toLowerCase().includes(query)
  );

  if (category) {
    setFilteredRecipes(result.filter(recipe => recipe.category === category));
  } else {
    setFilteredRecipes(result);
  }
}, [searchQuery, category]);

This runs every time the search query or category changes.


📦 Step 4: Display Filtered Recipes

<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
  {filteredRecipes.length > 0 ? (
    filteredRecipes.map((recipe, i) => (
      <RecipeCard key={i} recipe={recipe} />
    ))
  ) : (
    <p className="text-center col-span-full">No recipes found.</p>
  )}
</div>

🧠 Bonus: Tips

  • Use toLowerCase() to make searching case-insensitive

  • Use Set to generate unique categories

  • Add debounce if your search data is large

  • For UX, make the clear button instantly reset filters


📈 SEO Keywords

  • React search filter tutorial 2025

  • Tailwind CSS form input search

  • Recipe search filter React example

  • Case-insensitive search with useEffect

  • Responsive dropdown in React + TailwindCSS