Wagner Fillio
Wagner Fillio

Reputation: 405

Run onchange event react

I am trying to run an onChange event on a select-react component, but I cannot change the default values. In addition to changing the options, I need to assign the selection values ​​to a state. When I remove the state, I am able to change the options normally.

I saved the code at codesandbox for verification.

const options = [
  {
    label: "Queue 1",
    value: 0
  },
  {
    label: "Queue 2",
    value: 1
  },
  {
    label: "Queue 3",
    value: 2
  }
];

const defaultOptions = [
  {
    label: "Queue 1",
    value: 0
  },
  {
    label: "Queue 3",
    value: 2
  }
];

const App = () => {
  const [selectedQueue, setSelectedQueue] = useState([]);

  const handleChange = async (e) => {
    const value = e.map((x) => x.value);
    console.log(value);

    // if you comment the two lines, below I have no problems
    setSelectedQueue(value);
    console.log(selectedQueue);
  };

  const CustomSelect = (props) => (
    <Select
      options={options}
      defaultValue={defaultOptions}
      className="custom-select"
      onChange={handleChange}
      {...props}
    />
  );

  return (
    <div className="App">
      Multiselect:
      <CustomSelect isMulti />
    </div>
  );
};
export default App;

Upvotes: 0

Views: 62

Answers (1)

Ori Drori
Ori Drori

Reputation: 191976

You are recreating CustomSelect component on each render, which means that the component is remounted on each render, and the defaultValue is applied again. Extract the component out of the App component (sandbox):

const CustomSelect = (props) => <Select className="custom-select" {...props} />;

And pass the props to the component, when you render it in App:

const App = () => {
  const [selectedQueue, setSelectedQueue] = useState([]);

  const handleChange = async (e) => {
    const value = e.map((x) => x.value);
    console.log(value);

    // if you comment the two lines, below I have no problems
    setSelectedQueue(value);
    console.log(selectedQueue);
  };

  return (
    <div className="App">
      Multiselect:
      <CustomSelect
        options={options}
        defaultValue={defaultOptions}
        onChange={handleChange}
        isMulti
      />
    </div>
  );
};

Upvotes: 2

Related Questions