JedWatson / react-select

The Select Component for React.js
https://react-select.com/
MIT License
27.63k stars 4.13k forks source link

onChange doesn't work properly with AsyncSelect #5109

Closed usuallyno closed 2 years ago

usuallyno commented 2 years ago

Hi folks! I am using react-hook-form v7.28 controller with react-select v5.2.2. I have some problem with the onChange prop. It seems that the option is selected and stored with useState, but in the asyncselect component the option doesn't show up and the multiselect doesn't work. This is my code:

import "./styles.css";
import { useState } from "react";
import AsyncSelect from "react-select/async";
import { useForm, Controller } from "react-hook-form";

export default function App() {
  const [onChangeValue, setOnChangeValue] = useState([]);
  const { control } = useForm();

  const loadOptions = async (inputValue, callback) => {
    const response = await fetch(
      "https://anapioficeandfire.com/api/houses?region"
    );

    const resJson = await response.json();

    return resJson.reduce(
      (acc, curr) => (acc = [...acc, { value: curr.name, label: curr.name }]),
      []
    );
  };

  const onChange = (e) => {
    console.log("Selected Value:", e);
    setOnChangeValue(e);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Controller
        name="destination"
        onSelect={() => console.log("click")}
        render={({ field }) => (
          <AsyncSelect
            isMulti
            {...field}
            id="destination"
            instanceId="destination"
            cacheOptions
            defaultOptions
            loadOptions={loadOptions}
            onChange={onChange}
          />
        )}
        control={control}
        defaultValue=""
      />

      <p>Selected Value: {onChangeValue[0]?.label || ""}</p>
    </div>
  );
}

And this is the codebox example: https://codesandbox.io/s/vibrant-phoebe-80ggeb

Any thoughts? :)

Overdrive141 commented 2 years ago

Remove defaultValue prop then try

usuallyno commented 2 years ago

Remove defaultValue prop then try

~~It works! Thank You. It wasn’t a bug, I’m sorry, was just my fault.~~

Edit: the problem was that all the props of the controller component MUST to be initialized before the AsyncSelect component.

With this correction all works. My fault!

import "./styles.css";
import { useState } from "react";
import AsyncSelect from "react-select/async";
import { useForm, Controller } from "react-hook-form";

export default function App() {
  const [onChangeValue, setOnChangeValue] = useState([]);
  const { control } = useForm();

  const loadOptions = async (inputValue, callback) => {
    const response = await fetch(
      "https://anapioficeandfire.com/api/houses?region"
    );

    const resJson = await response.json();
    console.log(resJson);

    return resJson.reduce(
      (acc, curr) => (acc = [...acc, { value: curr.name, label: curr.name }]),
      []
    );
  };

  const onChange = (e) => {
    console.log("Selected Value:", e);
    setOnChangeValue(e);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Controller
        name="destination"
        onSelect={() => console.log("click")}
        control={control}
        render={({ field }) => (
          <AsyncSelect
            isMulti
            {...field}
            id="destination"
            instanceId="destination"
            cacheOptions
            defaultOptions
            loadOptions={loadOptions}
            onChange={onChange}
          />
        )}

      />

      <p>Selected Value: {onChangeValue[0]?.label || ""}</p>
    </div>
  );
}