Home > Back-end >  Is there a way in React to change option in select by clicking on another select?
Is there a way in React to change option in select by clicking on another select?

Time:09-20

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>

CodePudding user response:

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.

CodePudding user response:

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">
                {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.

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

    const handleSelection = (e) => {
        list.find(item => {
            if (item.country === e.target.value) {
                setRanking(item.options)
            }
        })
    }
  • Related