question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to set value of AsyncSelect outside of the component?

See original GitHub issue

I have read all the documentation of AsyncSelect and Select but I didn’t read anything regarding this matter. The problem arose after upgrading from V1 to V3. In V1, I could set value property (a simple value or string) and this would trigger the async loading procedure which would get the right value object (label and value). But, in V3, you should set value with the whole structure, eg, {label: xxx, value: yyy} in order to show it correctly.

For instance, we have this sample:

import React, { Component } from 'react';
import AsyncSelect from 'react-select/async';
import { colourOptions } from '../data';

type State = {
  inputValue: string,
};

const filterColors = (inputValue: string) => {
  return colourOptions.filter(i =>
    i.label.toLowerCase().includes(inputValue.toLowerCase())
  );
};

const promiseOptions = inputValue =>
  new Promise(resolve => {
    setTimeout(() => {
      resolve(filterColors(inputValue));
    }, 1000);
  });

export default class AsyncMulti extends Component<*, State> {
  state = { inputValue: '' };
  handleInputChange = (newValue: string) => {
    const inputValue = newValue.replace(/\W/g, '');
    this.setState({ inputValue });
    return inputValue;
  };
  render() {
    return (
      <AsyncSelect
        isMulti
        cacheOptions
        defaultOptions
        value = {1} // this won't work
        value = {{value: 1, label: "black"}}
        loadOptions={promiseOptions}
      />
    );
  }
}


All the logic of loading colors is inside the component. In order to set a value from outside, I would have to (in an external procedure) load the array and search for the value which, I think, would duplicate code unnecessarily.

Is there a way to set a value and this would trigger internal loading procedure in order to search for the correct pair?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:13

github_iconTop GitHub Comments

8reactions
stefanovernacommented, Apr 16, 2021

This is what works for me:

import AsyncSelect from 'react-select/async';
import { client } from 'api/dato';
import debounce from 'debounce-async';
import { useMemo, useState } from 'react';

const isOptionSelected = (option, values) => {
  return values.some(({ value }) => option.value === value);
};

export default function AccountInput({ field, form }) {
  const [lastOptions, setLastOptions] = useState([]);

  const loadOptions = useMemo(() => {
    return debounce(async (inputValue) => {
      const { data } = await client
        .url('/accounts')
        .query({ q: inputValue, id: field.value })
        .get()
        .json();

      const options = data.map((account) => ({
        value: account.id,
        label: `${account.attributes.email} (#${account.id})`,
      }));

      setLastOptions(options);

      return options;
    }, 300);
  }, [field.value, setLastOptions]);

  return (
    <div>
      <AsyncSelect
        cacheOptions
        loadOptions={loadOptions}
        defaultOptions
        isOptionSelected={isOptionSelected}
        value={lastOptions.find((option) => option.value === field.value)}
        onChange={(option) => {
          form.setFieldValue(field.name, option.value);
        }}
      />
    </div>
  );
}
8reactions
MarcosCunhaLimacommented, Oct 11, 2019

Yes, this is what I’ve done. But I have to (as you said) change my query (outside of the component) and manually craft a label/value object. The problem with this approach is that I had to duplicate this query (one query to search for the label before creating the component) and the other inside the component to loadOptions. Before this version, I could just set the value and it will trigger loadOptions and make this label/value automatically.

Read more comments on GitHub >

github_iconTop Results From Across the Web

AsyncSelect: how to set an initial value? - Stack Overflow
I am using AsyncSelect and need to change the value of the component based on outside logic. For instance, I have this simple...
Read more >
Async - React Select
Use the Async component to load options from a remote source as the user ... described by your loadOptions, to get those initial...
Read more >
How to use the react-select.Async function in react-select | Snyk
To help you get started, we've selected a few react-select. ... const SelectBT = ({ col, options, async, name, onChange, value, list, className...
Read more >
Selects - React Magma
A Select component allows the user to choose one or more item from a list. By default, only one item may be selected....
Read more >
chakra-react-select - npm
This type is made to give you a base to extend off of and pass in as a generic to the root Select...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found