How can I use React hooks to filter a course array with checkboxes based on unique tags?

I’m working on a React project where I need to filter an array of course objects using checkboxes. Each course has a unique tag, and I want to display courses based on the selected tags. Here’s what I’ve tried:

import React, { useState } from 'react';

const lessonData = [
  { id: 1, title: 'Introduction to HTML', category: 'web' },
  { id: 2, title: 'CSS Basics', category: 'web' },
  { id: 3, title: 'JavaScript Fundamentals', category: 'programming' },
  { id: 4, title: 'Python for Beginners', category: 'programming' },
  { id: 5, title: 'Database Design', category: 'data' },
];

const uniqueCategories = [...new Set(lessonData.map(lesson => lesson.category))];

function CourseFilter() {
  const [selectedCategories, setSelectedCategories] = useState([]);
  const [filteredLessons, setFilteredLessons] = useState(lessonData);

  const handleCategoryChange = (category) => {
    // Update selected categories and filter lessons
    // This part isn't working as expected
  };

  return (
    <div>
      {/* Render checkboxes and filtered lessons */}
    </div>
  );
}

export default CourseFilter;

The checkboxes render correctly, but I’m stuck on how to update the selected categories and filter the lessons accordingly. Any help would be appreciated!

hey there! i’ve dealt with similar stuff before. try updating ur handleCategoryChange like this:

const handleCategoryChange = (category) => {
  setSelectedCategories(prev => 
    prev.includes(category) ? prev.filter(c => c !== category) : [...prev, category]
  );
};

then use useEffect to filter lessons when selectedCategories changes. hope this helps!

Hey Ava_Books! :wave: That’s a cool project you’re working on! I’m curious, have you thought about using the useEffect hook to handle the filtering? It could make things a lot smoother. :thinking:

Something like this might work:

useEffect(() => {
  const filtered = selectedCategories.length === 0
    ? lessonData
    : lessonData.filter(lesson => selectedCategories.includes(lesson.category));
  setFilteredLessons(filtered);
}, [selectedCategories]);

This way, your filtered lessons update automatically whenever the selected categories change. Pretty neat, right?

Also, for your checkbox rendering, you could do something like:

{uniqueCategories.map(category => (
  <label key={category}>
    <input
      type="checkbox"
      checked={selectedCategories.includes(category)}
      onChange={() => handleCategoryChange(category)}
    />
    {category}
  </label>
))}

What do you think? Does this fit with what you’re trying to do? Let me know if you need any clarification or have other ideas! :blush:

I’ve implemented a similar feature in one of my projects. Here’s an approach that worked well for me:

For the handleCategoryChange function, you can toggle categories in and out of the selectedCategories state:

const handleCategoryChange = (category) => {
setSelectedCategories(prev =>
prev.includes(category) ? prev.filter(c => c !== category) : […prev, category]
);
};

Then, use the useEffect hook to filter lessons whenever selectedCategories changes:

useEffect(() => {
const filtered = selectedCategories.length === 0
? lessonData
: lessonData.filter(lesson => selectedCategories.includes(lesson.category));
setFilteredLessons(filtered);
}, [selectedCategories]);

This setup ensures your filtered lessons update automatically when categories are selected or deselected. It’s efficient and keeps your component’s logic clean and reactive.