Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In React, How to update state between multiple select dropdowns , each with same options?

I have a problem where I have to render 4 dropdowns, each with similar options(i just rendered 1 here). If I select an option in any one of the dropdowns, that option should not be available in the other three.

How should I update the selected_planets in the state? The below code updates the selected_planets from 1 select dropdown. But still that same option is available everywhere and I could not able to get 4 different options inside selected_planets array? How should I proceed?

Also, the response from API fetch is an array of objects, which I mapped through and update in planets Array. For demo purpose, let's consider, planets: [Neptune, Saturn, Mars, Earth, Venus, Jupiter]

import React, { Component } from 'react';

export default class Dashboard extends Component {
  state = {
    planets: [],
    selected_planets: []
  };

  componentDidMount() {
    fetch('url')
    .then(response => {
      return response.json();
    })
    .then(data => {
      this.setState({ planets: data });
    });
  }

  handleSelect = event => {
    this.setState({ selected_planets: [event.target.value] });
  };

  render() {
    let select_Planets = this.state.planets.map(planet => {
      return planet.name;
    });
    let options = select_Planets.map(planet => (
      <option key={planet} value={planet}>
        {planet}
      </option>
    ));

    return (
      <select onChange={this.handleSelect}>
        <option defaultChecked></option>
          {options}
      </select>
    );
  }
}
like image 399
Deepika Deepi Avatar asked Sep 29 '19 17:09

Deepika Deepi


People also ask

How do you select multiple options in a select tag in React?

The first and foremost thing we need to do is change the select element and make it let use select multiple values. The second thing we need to change is the constructor method and add an array so that we can use that array to store multiple selections from the user.

How do I update states in React?

To update our state, we use this. setState() and pass in an object. This object will get merged with the current state. When the state has been updated, our component re-renders automatically.


1 Answers

This can be achieved by producing a new set of options for each dropdown on render based off of what are the currently selected options, and what is the selected option for that dropdown.

First make sure each dropdown is binding to a property in your component's state and updating on change:

  constructor() {
    super();
    this.state = {
      planets: ["a", "b", "c", "d"],
      inputs: {
        d1: "",
        d2: ""
      }
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange({ target }) {
    this.setState({
      ...this.state,
      inputs: {
        ...this.state.inputs,
        [target.name]: target.value
      }
    });
  }
<select
  name="d1"
  value={this.state.inputs.d1}
  onChange={this.handleChange}>

Then you can obtain a list of the selected planets within the render method by converting the input object into an array using Object.values():

const selectedPlanets = Object.values(this.state.inputs);

Then create a new array for each of the dropdowns which will omit any planets which have already been selected unless it is selected by that particular dropdown itself:

const d1Options = this.state.planets.filter(
  p => !selectedPlanets.find(sP => sP === p) || p === this.state.inputs.d1
);
const d2Options = this.state.planets.filter(
  p => !selectedPlanets.find(sP => sP === p) || p === this.state.inputs.d2
);
<select
 name="d1"
 value={this.state.inputs.d1}
 onChange={this.handleChange}>
    <option></option>
    {d1Options.map(o => (
      <option key={o}>{o}</option>
    ))}
</select>

I've put together a working example here:

https://codepen.io/curtis__/pen/pozmOmx

like image 110
Curtis Avatar answered Sep 30 '22 07:09

Curtis