3

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 ?

yaser.barati
  • 157
  • 1
  • 5
  • 13

2 Answers2

3

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

gdh
  • 13,114
  • 2
  • 16
  • 28
1

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>
  );
}
Amila Dulanjana
  • 1,884
  • 1
  • 16
  • 33
  • tanx @Amila This is great.The only problem is that it doesn't show the last choice. Can you help please? – yaser.barati Apr 11 '20 at 07:05
  • @yaser.barati I updated the answer, please check. There are two options and you can select either one of them. You can use `useEffect` or else you can handle the logic inside the `handleChange` function. – Amila Dulanjana Apr 11 '20 at 09:53