0

My goal is to create react-select selects using data from an endpoint where a query var of category (in this example flavours). So I want to dynamically create these select inputs and have set up a component to wrap the main react-select code so I only need one handler function.

Here's my main file

const flavours1 = [
  { value: "chocolate", label: "Chocolate" },
  { value: "strawberry", label: "Strawberry" }
];
const flavours2 = [
  { value: "banana", label: "Banana" },
  { value: "kiwi", label: "Kiwi" }
];

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      test: "test",
      selectedOptions: null
    };
  }

  // Here I want to setState but with the name of each SelectComponent as the key for each object and also push to the existing array rather than over writing it as is currently
  addSelectedOption = (...args) => {
    this.setState({
      selectedOptions: [args[0]]
    });
  };

  componentDidUpdate() {
    console.log(this.state);
  }

  render() {
    return (
      <div style={styles}>
        <SelectComponent
          name="flavours1"
          options={flavours1}
          addSelectedOption={this.addSelectedOption}
        />
        <SelectComponent
          name="flavours2"
          options={flavours2}
          addSelectedOption={this.addSelectedOption}
        />
      </div>
    );
  }
}

And the component:

    import Select from "react-select";

    export default class SelectComponent extends Component {
      constructor(props) {
        super(props);

        this.state = {
          selectedOptions: null
        };
      }

      render() {
        return (
          <form>
            <Select
              isMulti
              onChange={this.props.addSelectedOption}
              value={this && this.state ? this.state.option : null}
              options={this.props.options}
              ref={input => {
                this.selectField = input;
              }}
            />
          </form>
        );
      }
    }

Here's my example so far: https://codesandbox.io/s/llzw409n3z

So the two things I am struggling with are:

  • Pushing objects to state as an array, keeping all of the selected values (currently selecting on each different select over writes the other
  • Assigning each object a key based on the name prop of the SelectComponent

The goal is to get the structure

selectedOptions: [
  flavours1: [
    { value: "chocolate", label: "Chocolate" },
    { value: "strawberry", label: "Strawberry" }
  ],
  flavours2: [
    { value: "banana", label: "Banana" },
    { value: "kiwi", label: "Kiwi" }
  ],
];

1 Answer 1

1

Currently the react-select component does not provide the name of the component that triggered the change event. So you will need to add that by making the SelectComponent internally handle the onChange event and then pass the this.props.name to the addSelectedOption handler.

Add

  handleChange = (...args) => {
    this.props.addSelectedOption(this.props.name, ...args)
  }

and apply it

    <Select
      onChange={this.handleChange}
      ...
     />

Now on your add component you can use

  addSelectedOption = (name, options) => {
    this.setState(({selectedOptions})=>({
      selectedOptions: {
        ...selectedOptions,
        [name]: options
        }
    }))
  };

but you will have to initialize the state like

this.state = {
  test: "test",
  selectedOptions: {}
};

so that you can spread the selectedOptions when using setState.

Edit Multiple dynamic react-select

Sign up to request clarification or add additional context in comments.

1 Comment

This is great, I appreciate the detailed explanation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.