So I have 2 select fields. Then first select field is for categories; The other one is for subcategories. When the first field changes, the second field changes the list of options to choose, but the selected value of the second select field is still there. So I was wondering if there's a way to deselect the second value, when the first value changes.
Code:
import { useEffect, useState } from 'react';
// import categoryOptions from './categoryOptions';
import subcategoryOptions from './subcategoryOptions.json';
import Select from 'react-select';
const Info = ({
register,
errors,
product,
setValue,
getValues,
watchAllFields,
formStep,
unregister,
}) => {
const categories = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
];
const [selectedCategory, setSelectedCategory] = useState(null);
const [selectedSubcategory, setSelectedSubcategory] = useState(null);
const [subcategoryArray, setSubcategoryArray] = useState();
const [isChanged, setIsChanged] = useState(false);
useEffect(() => {
setSelectedSubcategory(null);
if (selectedCategory) {
const foundSubcategory = subcategories.filter(
(item) => item.category === selectedCategory.value
);
if (foundSubcategory) {
console.log(foundSubcategory);
setSubcategoryArray(foundSubcategory);
}
}
setIsChanged(true);
}, [selectedCategory]);
const subcategories = [
{ value: '', label: '⠀' },
{ value: 'eee', label: 'Chocolate', category: 'chocolate' },
{ value: 'e', label: 'zre', category: 'chocolate' },
{ value: 'es', label: 'Chooo', category: 'chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
];
return (
<section className='px-10'>
<div className='flex flex-col'>
<label htmlFor='title' className='pb-5 text-2xl text-white'>
Title
</label>
<input
type='text'
name='title'
className='text-white bg-indigo-900 border-indigo-900 input focus:bg-indigo-500'
placeholder='Try something creative (Required)'
maxLength={30}
{...register('title', {
required: {
value: true,
message: 'Title is required!',
},
})}
/>
{errors.title && (
<p className='mt-2 text-sm text-yellow-500'>{errors.title.message}</p>
)}
<h1 className='pt-10 pb-5 text-2xl text-white'>Gig Requierments</h1>
<textarea
type='text'
name='Requirements'
className='h-56 text-white bg-indigo-900 border-indigo-900 input focus:bg-indigo-500'
{...register('requirements')}
></textarea>
<h1 className='pt-10 pb-5 text-2xl text-white'>Category</h1>
<Select
defaultValue={selectedCategory}
onChange={setSelectedCategory}
options={categories}
/>
<Select
isClearable
defaultValue={selectedSubcategory}
onChange={setSelectedSubcategory}
options={subcategoryArray}
/>
</div>
</section>
);
};
export default Info;
Any help would be appreciated. Thanks.
CodePudding user response:
Just pass a custom handler to the first Select
that resets the second Select
's value, if the currently selected subcategory is not in the new category:
const isSubcategory = (subcategory, category) => { /* returns true if subcategory is a subcategory of category */ }
const handleCategoryChange = useCallback(value => {
if (!isSubcategory(selectedSubcategory, value)) {
setSelectedSubcategory(null);
}
setSelectedCategory(value);
}, [selectedSubcategory])
<Select
isClearable
defaultValue={selectedCategory}
onChange={handleCategoryChange}
options={subcategoryArray}
/>
If the selected subcategory is never a subcategory of another category you can even skip the check.
The effect is not required. It all depends on local state changes.