Is there a way in React to change option in select by clicking on another select?

Viewed 47

So basically if I set country in second dropdown to let's say Spain and then want to change the option in first select dropdown, how can I set second dropdown to go back to default value, in this case All Countries?

<select onClick={handleRankingsRange}>
    <option value='top 100'>top 100</option>
    <option value='top 200'>top 100-200</option>
    <option value='top 200+'>top 200+</option>
  </select>

  <select onClick={handleFilterCountry}>
    <option defaultValue='All Countries'>All Countries</option>
    {countries
      .filter((country) => country !== '')
      .sort()
      .map((country, index) => {
        return (
          <option value={country} key={index}>
            {country}
          </option>
        );
      })}
  </select>
2 Answers

You need to convert your select components to controlled components by using value and onChange like this:

import { useState } from "react";

const countries = ["Spain", "France", "Portugal", "Germany"];

export default function App() {
  const [selectedRange, setSelectedRange] = useState();
  const [selectedCountry, setSelectedCountry] = useState();

  const handleRankingsRange = (e) => {
    setSelectedRange(e.target.value);
    setSelectedCountry("");
  };

  const handleFilterCountry = (e) => {
    setSelectedCountry(e.target.value);
  };

  return (
    <div>
      <select value={selectedRange} onChange={handleRankingsRange}>
        <option value="top 100">top 100</option>
        <option value="top 200">top 100-200</option>
        <option value="top 200+">top 200+</option>
      </select>
      <select value={selectedCountry} onChange={handleFilterCountry}>
        <option value="">All Countries</option>
        {countries
          .filter((country) => country !== "")
          .sort()
          .map((country, index) => {
            return (
              <option value={country} key={index}>
                {country}
              </option>
            );
          })}
      </select>
      <br />
      selectedRange = {selectedRange}
      <br />
      selectedCountry = {selectedCountry}
    </div>
  );
}

You can take a look at this sandbox for a live working example of this solution.

[Edit] Added the second part of your question to set back to default "all countries"

if using a list (the list in my example will be an array with objects)

    let list = [
        {
            country: "Spain",
            options: ["one", "two", "three"],
        },
        ...
    ]

you could create a state (useState hook) based on the array.

Mapping that list for the options as you have done, you can also map the first selection based on the array that you would set in your state.

My render would look like this:

    return (
        <>
            <select name="rankings" id="selectRankings">
                {ranking.map((rank, index) => {
                    return (
                        <option key={index} value={rank}>{rank}</option>
                    )
                })}
            </select>
            <br/>
            <select onChange={(e)=>{handleSelection(e)}} name="countries" id="selectCountry">
                   <option value="All">All Countries</option>
                {list.map((item, index) => {
                    return(
                        <option key={index} value={item.country}>{item.country}</option>
                    )
                })}
            </select>
        < />
    );

when selecting a country, on change it will execute handleSelection which will find the correct options and update them to your state.

secondly, if you want to reset the value of the second selection element, you can just set it back to "All" (see code below)

    const [ranking, setRanking] = useState(["-- select country first --"]);

    const handleSelection = (e) => {
        list.find(item => {
            if (item.country === e.target.value) {
                setRanking(item.options)
            }
        })
        e.target.value = "All";
    }

sandbox example

Related