Невозможно управлять опорой Downshift selectedItem из родительского компонента с помощью контролируемых свойств

Я написал многоразовый компонент автозаполнения с помощью Downshift. Компонент инкапсулирует много логики Relay для получения данных из моей конечной точки GraphQL. У меня есть вариант использования, когда родительский компонент должен получить selectedItem, отобразить свойство name для selectedItem, а затем очистить selectedItem автозаполнения (подумайте о выборе и отображении нескольких тегов).

Проблема в том, что я не могу управлять selectedItem автозаполнения из родительского компонента. Я отправляю selectedItem как null для автозаполнения, но inputValue/selectedItem остается выбранным элементом.

Пример кода с удаленным Relay для простоты:

https://codesandbox.io/embed/spring-fire-um1xh

Действия по воспроизведению

  • Введите слово "Элемент" в текстовое поле.
  • Щелкните один из трех отображаемых результатов

Фактический результат

  • Заголовок родительского компонента и inputValue/selectedItem для автозаполнения устанавливаются равными значению выбранного элемента

Желаемый результат

  • Заголовок родительского компонента установлен на значение выбранного элемента
  • inputValue / selected Элемент автозаполнения очищен

1 ответ

Попробуйте код ниже. Этот код нуждается в большом рефакторинге, но он все равно работает по желанию. Итак, я просто добавил реквизиты inputValue в Downshift согласно документу.

----- index.js -------
function App() {
  const [title, setTitle] = useState("Select an Item");
  const [selectedItem, setSelectedItem] = useState(null);
  const [inputValue, setInputValue] = useState(""); //added these two to control input of inputbox

  const onItemSelected = selectedItem => {
    setTitle(selectedItem.name);
    setSelectedItem(null);
    setInputValue("") // after selection clear input
  };

  return (
    <div className="App">
      <h1>{title}</h1>
      <Autocomplete
        selectedItem={selectedItem}
        inputValue={inputValue} // passed down inputValue and setInputValue
        setInputValue={setInputValue}
        onItemSelected={onItemSelected}
      />
    </div>
  );
}

----Autocomplete.js--------
function Autocomplete({ selectedItem, onItemSelected, inputValue, setInputValue })  { // get those props
  const [items, setItems] = useState([]);

  const onInputValueChanged = e => {
    setInputValue(e.currentTarget.value) //change a input on inputchange
    const items = data.filter(f => f.name.includes(e.currentTarget.value));
    setItems(items);
  };

  return (
    <Downshift
      inputValue={inputValue} //added
      selectedItem={selectedItem}
      onChange={onItemSelected}
      itemToString={i => (i ? i.name : "")}
    >
      {({ getInputProps, getItemProps, getMenuProps, isOpen }) => (
        <div>
          <input {...getInputProps({ onChange: onInputValueChanged })} />
          <ul {...getMenuProps()}>
            {isOpen &&
              items.map(item => (
                <li {...getItemProps({ item, key: item.value })}>
                  {item.name}
                </li>
              ))}
          </ul>
        </div>
      )}
    </Downshift>
  );
}


Другие вопросы по тегам