how to merge selectedOptions in react-select

Viewed 706

I use react-select and I'm new.I have a component called Example

const colourOptions = [
  { value: '1', label: '1', color: '#00B8D9' },
  { value: '2', label: '2', color: '#0052CC' },
  { value: '3', label: '3', color: '#5243AA' },
];

class Example extends React.Component {
      state = {
        selectedOption: null,
      }

      render() {
        const { selectedOption, onHandleChange } = this.props;
        return (

          <Select
            onChange={onHandleChange}
            options={colourOptions}
          />

        );
      }
    }

    export default Example;

In another file we have a functional Component

export default function UserProfile() {
  const [selectedOption, setSelectedOption] = useState({});

  const handleChange = (selectedOption) => {
    setSelectedOption(selectedOption)
    console.log(selectedOption)
  };

  return (
    <div>

      <Example onHandleChange={handleChange} selectedOption={selectedOption}/>
      <Example onHandleChange={handleChange} selectedOption={selectedOption}/>
      <Example onHandleChange={handleChange} selectedOption={selectedOption}/>

    </div>
  );
}

By changing every Example, the value of the previous selectedOption is removed. how to put (merge) all selectedOptions inside one object ?

2 Answers

You will need to maintain a separate option values for all Example instances.

Like this:

export default function UserProfile() {
    const [selectedOption, setSelectedOption] = useState({ example1: '', example2: '', example3: '' });

    const handleChange = (key, selectedOption) => {
        setSelectedOption(prev => ({...prev, [key]: selectedOption}));
        console.log(selectedOption)
    };

    return (
        <div>
            <Example1 onHandleChange={(value) => handleChange('example1', value)} selectedOption={selectedOption.example1}/>
            <Example2 onHandleChange={(value) => handleChange('example3', value)} selectedOption={selectedOption.example2}/>
            <Example3 onHandleChange={(value) => handleChange('example3', value)} selectedOption={selectedOption.example3}/>
        </div>
    );
}

EDIT Working code is here:

https://codesandbox.io/s/eloquent-mclaren-8s2z2?file=/src/UserProfile.js

Also quick note - the state updates are asynchronous so when you do console.log right after setting state, you may see the log printing old state.

Read more here if you like

You can collect all the selected options into one Array. Please find the link to working solution https://codesandbox.io/s/react-example-xk3bw?fontsize=14&hidenavigation=1&theme=dark

import React, { useState,useEffect } from "react";
import Example1 from "./Example";
import Example2 from "./Example";
import Example3 from "./Example";

export function UserProfile() {
  const [selectedOption, setSelectedOption] = useState({});
  const [allselectedOption, setAllSelectedOption] = useState([]);

  useEffect(() => {
    console.log(allselectedOption);
 },[allselectedOption]);

  const handleChange = selectedOption => {
    setSelectedOption(selectedOption);
    let newSelectedOptions = [...allselectedOption,selectedOption]
    setAllSelectedOption(newSelectedOptions)
    console.log(newSelectedOptions);
  };

  return (
    <div>
      <Example1 onHandleChange={handleChange} selectedOption={selectedOption} />
      <Example2 onHandleChange={handleChange} selectedOption={selectedOption} />
      <Example3 onHandleChange={handleChange} selectedOption={selectedOption} />
    </div>
  );
}
Related