如何获取downshift useSelect选项变更时的真实触发事件
解决downshift useSelect无法获取真实事件触发item onClick的问题
你遇到的问题核心是onSelectedItemChange是downshift内部状态变更后的回调,并非直接绑定在DOM事件上,所以无法拿到原始触发事件。下面是可行的解决方案:
核心方案:自定义菜单项的点击事件处理
不依赖onSelectedItemChange,而是在渲染菜单项时,覆盖getItemProps返回的onClick,先获取真实事件传给item的onClick,再手动触发downshift的选中逻辑。
代码示例
import { useSelect } from 'downshift'; // 你的menuItems数组(无法修改) const menuItems = [{ label: 'foo', value: 'bar', onClick: (event) => doTheThing(event), }]; function YourSelectComponent() { const { getItemProps, getLabelProps, getMenuProps, getToggleButtonProps, highlightedIndex, isOpen, selectItem // 拿到downshift的手动选中方法 } = useSelect({ items: menuItems, // 可根据需求保留或移除onSelectedItemChange,用于其他状态同步 }); return ( <div> <label {...getLabelProps()}>选择项</label> <button {...getToggleButtonProps()}>{isOpen ? '关闭' : '打开'}</button> {isOpen && ( <ul {...getMenuProps()}> {menuItems.map((item, index) => { const baseProps = getItemProps({ item, index }); return ( <li key={item.value} {...baseProps} onClick={(event) => { // 先调用item自带的onClick,传入真实DOM事件 item.onClick(event); // 手动触发downshift的选中逻辑,维护内部状态 selectItem(item); }} style={{ backgroundColor: highlightedIndex === index ? '#eee' : 'transparent' }} > {item.label} </li> ); })} </ul> )} </div> ); }
说明
- 通过
selectItem方法手动触发downshift的选中状态更新,确保组件内部状态和原来的行为一致 - 直接在DOM的
onClick事件中获取真实的event对象,完美适配item中需要event参数的onClick函数 - 保留了
getItemProps返回的其他属性(如键盘导航相关的props),不会破坏downshift的原有交互逻辑
补充:处理键盘触发的选中(可选)
如果需要支持键盘回车选中时也传递event,可以监听菜单的键盘事件,示例如下:
const menuProps = getMenuProps({ onKeyDown: (event) => { if (event.key === 'Enter' && highlightedIndex !== null) { const selectedItem = menuItems[highlightedIndex]; selectedItem.onClick(event); selectItem(selectedItem); // 阻止默认行为避免页面跳转 event.preventDefault(); } }, });
在渲染菜单时使用{...menuProps}即可。
内容的提问来源于stack exchange,提问作者sfletche
相关产品推荐
相关产品推荐

