React-select: How to add created items to options list

Viewed 1500

So I'm using the Creatable component of the react-select library. I want to be able to add the created option into my options array on keyDown. How it looks right now

My states:

  const [value, setValue] = useState([]);
  const [inputValue, setInputValue] = useState('');
  const [selectedValues, setselectedValues] = useState([]);

  const [current, setCurrent] = useState([]);

  const [selection, setSelection] = useState(statusOptions);

My functions

 const handleInputChange = (value) => {
    setInputValue(value);
  };
  const handleOnChange = (haha) => {
    setCurrent(haha);
  };

  const handleKeyDown = () => {
    setTimeout(() => {
      setNewValues();
    }, [2700]);
  };

  const setNewValues = (event) => {
    const newOption = { label: inputValue, inputValue };
    inputValue !== '' && setSelection([...selection, newOption]);

    setCurrent(current);
    let difference = current.filter((x) => !value.includes(x));

    setInputValue('');

    setselectedValues(difference);
  };

How the component looks

<CreatableSelect
        options={selection}
        isMulti
        onChange={handleOnChange}
        onInputChange={handleInputChange}
        inputValue={inputValue}
        value={selectedValues.selected}
        inputValue={inputValue}
        onKeyDown={handleKeyDown}
      />

The problem: Right now, the inputValue is added to the dropdown list as the user types and i don't know why. I am able to add and delete the tags on keyDown. But when the user types slow or doesn't write quick enough, the dropdown list ends up with two created options.

2 Answers

So I was way over-complicating this. And thanks to the answer above, i was able to approach it better. I needed to be able to add the tags via keyboard, have them be added into the dropdown list, and then be able to get deleted. Here's the full answer

  const [inputValue, setInputValue] = useState('');
  const [selectedValues, setselectedValues] = useState({ selected: [] });

  const [selection, setSelection] = useState(statusOptions);

  const handleInputChange = (value) => {
    setInputValue(value);
  };

  const handleOnChange = () => {
    const newOption = { label: inputValue, inputValue };

    inputValue !== '' && setSelection([...selection, newOption]);

    setInputValue('');

    setselectedValues(selection);
  };

  return (
    <div>
      <CreatableSelect
        options={selection}
        isMulti
        onChange={handleOnChange}
        onInputChange={handleInputChange}
        inputValue={inputValue}
        value={selectedValues.selected}
        inputValue={inputValue}
        controlShouldRenderValue={true}
      />
    </div>

The option is getting added to the list because setNewValues is being called after the 2700 ms timer expires which is adding a new option item to the menu.

In order to achieve the behavior that you want, remove the onKeyDown function. This will allow you to enter tags without having them populate the menu.

Adding custom tag

Adding custom tag

Result of creating tag

Result of creating tag

Related