Learn how to filter Select list by another Select list in React using state, useEffect, event handlers, and filtered subcategories.
TL;DR
-
Filter Select list by Another Select list to create dependent dropdowns in a React application.
-
Use React state to store categories, all subcategories, and the filtered subcategory list.
-
Use
useEffectto fetch the categories and subcategories when the application loads. -
Filter subcategories based on the selected category ID and update the dependent Select list.
-
Reset the selected subcategory when the category changes to keep the form data consistent.
In this tutorial, I will show you how to filter a Dropdownlist based on another Dropdownlist in React. We would use the example of Product, Category and SubCategory to demonstrate this.
We would cover the following six steps
- Define the States
- Create the useEffect Hook to Fetch the Categories
- Create the useEffect Hook to Fetch the SubCategories
- Write the Categories <Select> and Handler
- Write the SubCategories <Select> and Handler
- Add Some Styling
1. Create the States
We would need states to hold the total categories list(categories, the complete subcategory list (allSubcategories) and the filtered sub-category list (filteredSubCategories)
These are defined as shown below:
const [categories, setCategories] = useState([]); const [allSubCategories, setAllSubCategories] = useState([]); const [filteredSubCategories, setFilteredSubCategories] = useState([]);
Also update the newProduct state to include categoryid and subcategoryid. This is shown below:
const [newProduct, setNewProduct] = useState({ title: '', summary: '', content: '', categoryid: '', subcategoryid: '', created_at: new Date().toISOString() // Set current datetime })
2. Create the useEffect Hook to Fetch Categories
We use the effect hook to load up the Categories when the application starts up.
useEffect(() => { axios.get('http://localhost:8081/categories').then((response) => { setCategories(response.data) }) .catch ((error) => { console.error('Error fetching categories:', error); }); }, []);
3. Create the useEffect Hook to Fetch SubCategories
We also want to load up the subCategories when the application starts up.
useEffect(() => { axios.get('http://localhost:8081/subCategories').then((response) => { setAllSubCategories(response.data); }) .catch((error) => { console.log('Error occurred fetching subcategories', error); }) }, []);
Update the Table: At this point you can update the table to include category and subcategory columns
4. Write the Categories Select and Handler
We load the categories into the <select> for categories. We also set the value to newProduct.categoryid. Also not the the default selected item is the text “Choose..” whose value defaults to empty string.
<select id="categoryid" onChange={handleCategoryChange} value={newProduct.categoryid} > <option >Choose...</option> {categories.filter(c => c.title != null).map(category => ( <option key={category.id} value={category.id}> {category.title} </option> ))} </select>
Write the event handler (handleCategoryChange): When the category is selected we do the following
- obtain the value of the category that was selected
- update the categoryid of the newProduct
- filter the subCategories base on the categoryid
const handleCategoryChange = (event) => { const selectedCategoryId = event.target.value; setNewProduct({ ...newProduct, categoryid: selectedCategoryId, subcategoryid: '' // Reset subcategory when category changes }); // Filter the subcategories based on the selected category const filteredSubCategories = allSubCategories.filter( (subCategory) => subCategory.categoryid === Number(selectedCategoryId) ); setFilteredSubCategories(filteredSubCategories); // Update the filtered subcategories }
5. Write the SubCategories Select and Handler
<select id="subcategoryid" value={newProduct.subcategoryid} onChange={handleSubCategoryChange}> <option>Choose...</option> {filteredSubCategories.map(subCategory => ( <option key={subCategory.id} value={subCategory.id}> {subCategory.description} </option> ))} </select>
In the handler for subCategories select, we simply obtain the selected sub-categoryid and use it to update the subcategoryid field of the newProduct
const handleSubCategoryChange = (event) => { const selectedSubCategoryId = event.target.value; setNewProduct({ ...newProduct, subcategoryid: selectedSubCategoryId }); };
6. Add Some Styling to the Select
We add some style to the <select> using the sx prop
style={{ width: '100%', // Makes it full width padding: '8px', // Adds padding for better UI borderRadius: '4px', // Adds rounded corners border: '1px solid #ccc', // Adds a border marginBottom: '16px', // Adds margin at the bottom fontSize: '16px', // Sets a readable font size }}
Now you can start the application and enjoy!!
FAQs
What does it mean to filter a Select list by another Select list in React?
It means creating dependent dropdowns where the options displayed in one Select list depend on the value selected in another Select list.
How do you create dependent Select lists in React?
Use React state to store the complete lists and a filtered list, then update the filtered list when the value of the first Select list changes.
How are categories and subcategories connected in this tutorial?
Each subcategory has a category ID, which is compared with the selected category ID to determine which subcategories should be displayed.
Why should the subcategory be reset when the category changes?
Resetting the subcategory prevents a previously selected subcategory from remaining selected when it may no longer belong to the newly selected category.
Which React features are used to filter the Select list?
The tutorial uses useState, useEffect, event handlers, JavaScript’s filter() method, and React’s map() method to create the dependent dropdowns.
Final Thoughts
Filtering a Select list by another Select list is a common requirement when building React forms with related data. In this example, categories control which subcategories are displayed, creating a simple dependent dropdown experience.
The approach is straightforward: load the data, store it in state, filter the subcategories when a category is selected, and update the second Select list. Resetting the subcategory when the category changes also helps keep the form state consistent.
Once you understand this pattern, you can apply the same approach to other related selections such as country and state, department and employee, or product and category.