0
votes

I'm trying to make multiple selection-inputs using React and react-select.

How can I manage elements with multiple states?

I make elements using loop (map) and after that how can I determine what value is going to be the next value for value prop?

How can I somehow save values that I got from onChange callback as states, and then assign it to proper element?

Now whenever I change my input (onChange calls handleChange), it's saving current selected value (as expected) but when I change input in another element, the previous element value goes back to "", and I'm only changing values in the current one.

handleChange(el) {
    this.setState({
        value:el
    })
}

let options = values.map(value => {
                return {
                        value: value.name,
                        label: value.name,
                        category: el,
                        categoryName: data[el].name
                    }
            })

<Select 
 name={el}
 className='Select-filters'
 closeOnSelect={false}
 onChange={this.handleChange}
 noResultsText='Filter couldn't be found'
 placeholder={`Search ${nameNotCapitalized}`}
 options={options}
 delimiter=';'
 simpleValue
 value={value}
 multi
/>
1
does your select inputs have the same options? - AngelSalazar
No, I'm generating it based on api data - Kacper Ochmański

1 Answers

2
votes

I believe this is what you are looking for

class App extends React.Component {
  constructor (props) {
    super(props);
    // I am storing the inputs definition here, but
    // it could be something that you retrieve from
    // your redux store or an API call
    this.state = {
      inputs : [{
        name : 'vowels',
        value : 'a',
        options : ['a','b','c']
      }, {
        name : 'numbers',
        value : 1,
        options : [1,2,3]
      }]
    }
  }
  // createSelect creates the select input based
  // on the input definition in the state
  createSelect (inputOptions) {
    const {options} = inputOptions;
    // Create options for the select
    const opts = options.map((o) => {
      return (<option value={o}>{o}</option>)
    });
    // Choosing the value
    // if the state does not have a key with the name
    // of the select yet, then use the value of the input definition
    // when the select change its value this.state[inputOptions.name]
    // will be used
    const val = this.state[inputOptions.name] || inputOptions.value
    return (
      <select value={val} onChange={this.createChangeHandler(inputOptions.name)}>
        {opts}
      </select>
    )
  }
  // createChangeHandler is a curried function that
  // allows to specify which state value will be set
  createChangeHandler (field) {
    return (e) => {
      this.setState({
        [field] : e.target.value
      })
    }
  }

  renderSelects () {
    const {inputs} = this.state;
    return inputs.map((input) => {
      return this.createSelect(input)
    });
  }

  render () {
    return (
      <form>
        {this.renderSelects()}
      </form>
    );
  }
}


ReactDOM.render(
  <App/>, 
  document.querySelector('#root')
)

and there is a demo