江户川乱折腾
上述行为可以利用stateReduceranduseCombobox钩子实现,如下所示:import React, { useState } from "react";import { render } from "react-dom";import { useCombobox } from "downshift";import { items, menuStyles } from "./utils";function stateReducer(state, actionAndChanges) { switch (actionAndChanges.type) { case useCombobox.stateChangeTypes.InputChange: return { ...actionAndChanges.changes, userInput: actionAndChanges.changes.inputValue }; case useCombobox.stateChangeTypes.InputKeyDownArrowDown: case useCombobox.stateChangeTypes.InputKeyDownArrowUp: if (!actionAndChanges.changes.inputValue) return actionAndChanges.changes; return { ...actionAndChanges.changes, userInput: actionAndChanges.changes.inputValue, inputValue: actionAndChanges.getItemNodeFromIndex( actionAndChanges.changes.highlightedIndex ).innerText }; default: return actionAndChanges.changes; // otherwise business as usual. }}function DropdownSelect() { const [inputItems, setInputItems] = useState(items); const { isOpen, getToggleButtonProps, getLabelProps, getMenuProps, getInputProps, getComboboxProps, highlightedIndex, getItemProps } = useCombobox({ items: inputItems, stateReducer, onInputValueChange: ({ userInput, inputValue }) => { if (userInput === inputValue) { const filteredItems = items.filter(item => item.toLowerCase().startsWith(inputValue.toLowerCase()) ); setInputItems(filteredItems); } } }); return ( <React.Fragment> <label {...getLabelProps()}>Choose an element:</label> <div style={{ display: "inline-block" }} {...getComboboxProps()}> <input {...getInputProps()} /> <button {...getToggleButtonProps()} aria-label="toggle menu"> ↓ </button> </div> <ul {...getMenuProps()} style={menuStyles}> {isOpen && inputItems.map((item, index) => ( <li style={ highlightedIndex === index ? { backgroundColor: "#bde4ff" } : {} } key={`${item}${index}`} {...getItemProps({ item, index })} > {item} </li> ))} </ul> </React.Fragment> );}render(<DropdownSelect />, document.getElementById("root"));