如何在TextField的onChange事件中读取MenuItem的data属性?
我使用Material-UI的TextField组件(select模式),搭配多个MenuItem,想要在onChange事件中获取每个MenuItem的额外标识(比如option.id)。尝试给MenuItem加data-option-id属性,但在事件回调里读不到这个值。
代码示例
function MyComponent({options}) { const [value, setValue] = useState<string>(''); const changeHandler = (e: React.ChangeEvent<HTMLInputElement>) => { // 这里想读取option-id并处理 setValue(e.target.value); }; return ( <TextField select onChange={changeHandler} value={value}> { options.map( (option) => <MenuItem key={option.id} value={option.value} data-option-id={option.id}> {option.value} </MenuItem> ) } </TextField> ); }
限制说明
- 不能把option.id设为MenuItem的value(必须用option.value,且该值不唯一)
- 希望继续使用TextField组件,不自定义
- 当前e.target只能拿到value和name,获取不到额外属性
解决方案
方法1:通过事件的composedPath定位MenuItem
MUI的Select组件会包裹原生元素,e.target是内部的input,我们可以用composedPath()找到对应的MenuItem元素,进而读取data属性:
const changeHandler = (e: React.ChangeEvent<HTMLInputElement>) => { // 从事件路径里找到LI标签(MenuItem渲染后的标签) const menuItem = e.composedPath().find(el => (el as HTMLElement).tagName === 'LI'); if (menuItem) { const optionId = (menuItem as HTMLElement).dataset.optionId; // 在这里处理拿到的optionId console.log('选中的选项ID:', optionId); } setValue(e.target.value); };
方法2:通过选中的value映射回原option对象
利用传入的options数组,根据选中的value匹配对应的option,直接获取id:
const changeHandler = (e: React.ChangeEvent<HTMLInputElement>) => { const selectedValue = e.target.value; // 注意:如果value不唯一,这里会返回第一个匹配的option,需根据业务调整逻辑 const selectedOption = options.find(opt => opt.value === selectedValue); if (selectedOption) { console.log('选中的选项ID:', selectedOption.id); // 处理选中的option.id } setValue(selectedValue); };
方法3:给MenuItem绑定独立的点击事件
直接给每个MenuItem添加onClick回调,点击时直接传递完整的option对象,无需依赖DOM属性:
function MyComponent({options}) { const [value, setValue] = useState<string>(''); const handleMenuItemClick = (option) => { setValue(option.value); // 直接拿到option.id进行处理 console.log('选中的选项ID:', option.id); }; return ( <TextField select value={value}> { options.map(option => ( <MenuItem key={option.id} value={option.value} onClick={() => handleMenuItemClick(option)} > {option.value} </MenuItem> )) } </TextField> ); }
内容的提问来源于stack exchange,提问作者jahu
相关产品推荐
相关产品推荐

