Home > Net >  How to clear a select field when another select field changes with react-select
How to clear a select field when another select field changes with react-select

Time:04-09

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.

  • Related