1

我使用 Downshift 中的 useCombobox 作为 use-hook-form 组件,一切正常,除了当用户键入不在传递到 useComboBox 的列表中的值时,我无法获取该值。

除非值在 inputItems 中,否则永远不会触发 onSelectedItemChange。这似乎应该很容易,但我无法从文档中找到答案。

import React, { memo, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useCombobox } from 'downshift';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronDown } from '@fortawesome/free-solid-svg-icons';

const comboboxStyles = { display: 'inline-block', marginLeft: '5px' };

let Item = ({ isHighlighted, getItemProps, item, index }) => {
  return (
    <li
      className="auto-complete-list-item"
      style={isHighlighted ? { backgroundColor: '#bde4ff' } : {}}
      key={`${item}${index}`}
      {...getItemProps({ item, index })}
    >
      {item}
    </li>
  );
};

Item = memo(Item);

const Autocomplete = ({ items, onChange, isSubmitting }) => {
  const [inputItems, setInputItems] = useState(items);
  const {
    isOpen,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    getInputProps,
    getComboboxProps,
    highlightedIndex,
    getItemProps,
    inputValue,
    reset
  } = useCombobox({
    items: inputItems,
    onSelectedItemChange: ({ inputValue }) => onChange(inputValue),
    onInputValueChange: ({ inputValue }) => {
      setInputItems(
        items.filter(item =>
          item.toLowerCase().includes(inputValue.toLowerCase())
        )
      );
    }
  });

  useEffect(() => {
    if (inputValue.length > 0 && isSubmitting) reset();
  }, [inputValue, isSubmitting, reset]);

  return (
    <div className="input-field">
      <div style={comboboxStyles} {...getComboboxProps()}>
        <input name="autocomplete" {...getInputProps()} />
        <button
          type="button"
          {...getToggleButtonProps()}
          aria-label="toggle menu"
        >
          <FontAwesomeIcon icon={faChevronDown} />
        </button>
      </div>
      <ul {...getMenuProps()} className="auto-complete-list">
        {isOpen &&
          inputItems.map((item, index) => (
            <Item
              key={item}
              isHighlighted={highlightedIndex === index}
              getItemProps={getItemProps}
              item={item}
              index={index}
            />
          ))}
      </ul>
    </div>
  );
};

Autocomplete.propTypes = {
  list: PropTypes.array
};

export default Autocomplete;
4

1 回答 1

0

您需要控制项目选择:

const {
    isOpen,
    selectItem,
    getToggleButtonProps,
    ...
}

然后在 onClick 处理程序中调用 selectItem:

    <Item
        key={item}
        onClick={() => selectItem(item)}
        isHighlighted={highlightedIndex === index}
        ...
    />
于 2020-12-06T01:20:43.113 回答