Skip to content
Advertisement

React Hook Form – Controller – React AsyncSelect – Lodash Debounce | Failed showing loadOptions

React hook not showing option in loadingOptions in AsyncSelect when I use debounce from lodash.

Here is the code.

const NoteFormMaster = ({ register, control, errors }) => {
  
  const getAsyncOptions = (inputText) => {
    return axios
      .get(`/v1/user?username=${inputText}`)
      .then((response) => {
        return response.data.map((user) => ({
          value: user.id,
          label: user.username,
        }));
      })
      .catch((error) => {
        alert(JSON.stringify(error));
      });
  };

  const loadOptions = (inputText) => getAsyncOptions(inputText);
  const debounceLoadOptions = _.debounce(loadOptions, 3000);

  return (
    <Controller
        control={control}
        name="shareWith"
        id="shareWith"
         as={
           <AsyncSelect
              // cacheOptions
              loadOptions={(v) => debounceLoadOptions(v)}
              defaultValue={[]}
              isMulti
              isClearable
              defaultOptions={[]}
           />
         }
      />
    )
  );
};

But, when I am not use debounce like loadOptions={(v) => getAsyncOptions(v)} It works. How to handle this debounce?

Advertisement

Answer

loadOptions expects that a callback parameter is called with the new options or that a promise is returned. Your debounceLoadOptions returns a function wrapped in a debounce function so it does not fulfill either of these requirements.

Given your implementation, I would replace the loadOptions functions declaration like this.

  const loadOptions = React.useCallback(
    debounce((inputText, callback) => {
      getAsyncOptions(inputText).then((options) => callback(options));
    }, 3000),
    []
  );

Also there is no need to declare the loadOptions prop as is. It should be noted that the loadOptions prop actually passes two parameters back and the second one is needed in this case to set the new options so the select can be rendered like this:

<AsyncSelect
  // cacheOptions
  loadOptions={loadOptions}
  defaultValue={[]}
  isMulti
  isClearable
  defaultOptions={[]}
/>

Here is the corresponding codesandbox to try it out: https://codesandbox.io/s/react-select-async-debounce-usecallback-oeixm?file=/src/App.js

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement