How can we handle disabling of dropdown selection in react hooks web app without refreshing the page?

80 Views Asked by At

How can we handle disabling of dropdown selection in react hooks web app without refreshing the page ? In my case, I have a multiselect dropdown box. When I selected an item from the dropdown, display a text field, once after typing some text and submit it, details get saved into database. Once saved into DB, the respective dropdown item should be disabled for selection.

enter image description here

But in my case, its not immediately disabled after submit. Its is disabled only after i manually refresh the page. How can I fix this issue, can someone please advise ?

  const [option, setOption] = useState([]);
  const [selectedOption, setSelectedOption] = useState([]);
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
    reset,
  } = useForm();

  const refSelect = useRef(null);
  const [submittedNominees, setSubmittedNominees] = useState([{}]);
  const [maxOptions, setMaxOptions] = useState(0); 
  const [showOptions, setShowOptions] = useState(false); 


    const focusOnInput = () => {
        setTimeout(() => {
          document.querySelector("input").focus();
        // Adding some delay to allow the component to re-mount
        }, 10);
      };
    
      const handleTypeSelect = (e, i) => {
        const copy = [...selectedOption];
        copy.push(e[3 - maxOptions]); //A.H-fix error: select one more record it still console log the pre selected one
        setSelectedOption(copy);
        setMaxOptions((prevState) => prevState - 1); //A.H-making maxOption dynamic
        focusOnInput();
      };
    
      const handleTypeRemove = (e) => {
        const copy = [...selectedOption];
        let index = copy.indexOf(e);
        copy.splice(index, 1);
        setSelectedOption(copy);
        setMaxOptions((prevState) => prevState + 1);         
        // immutating state (best practice)
        const updateList = nomRegister.map((item) => {
          return { ...item };
        });
        //delete the specific array case depends on the id
        updateList.splice(index, 1);
        setNomRegister(updateList);
        focusOnInput();
      };
    
    
        useEffect(() => {
            const fetchData = async () => {
              const userEmail = localStorage.getItem("loginEmail");
              try {
                let res = [];
                res = await Axios.get(
                  `${appURL}/service/submittednominations`,
                    {params:{userEmail}}
                );
                const data1 = res.data;
                console.log(data1, "data1");
                  setSubmittedNominees(data1);
                  setMaxOptions(3 - data1.length); //maxOption dynamic because we don't the length of data from submittednominations
                  console.log("Submitted nominations :" + JSON.stringify(data1));
              } catch (e) {
                console.log(e);
              }
            };
            fetchData();
          }, []);

Droddown box:

<section className="col1">
        <div className='nomineeSelectBox'>
          <div id='dialog2' className='triangle_down1' />
          <div className='arrowdown'>
            <Multiselect
              ref={refSelect}
              onSelect={(e) => handleTypeSelect(e, selectedOption.length)}
              onRemove={handleTypeRemove}
              options={!showOptions ? [] : option}
              displayValue='displayValue'
              disablePreSelectedValues={true}
              selectedValues={submittedNominees}
              showCheckbox={true}
              emptyRecordMsg={"Maximum nominees selected !"}
            />
          </div>
        </div>
      </section>
1

There are 1 best solutions below

0
Fody On

If you add the changed state to the dependency list of the useEffect(), it will re-run that section of code inside.

useEffect(() => {
  // this code will re-run every time "selectedOptions" is changed
  // therefore every time "handleTypeSelect()" or "handleRemove()" is run
  const fetchData = async () => {
    ...
}, [selectedOption])  

This will trigger a fresh list of submittedNominees, and cause a rerender (just the component, not the whole page) because submittedNominees is one of the render properties

<Multiselect
  ...
  selectedValues={submittedNominees}
  ...
  />

Alternatively (and probably quicker UI), make a call to setSubmittedNominees() inside handleTypeSelect() and handleRemove(). That will also trigger a component rerender.