React MUI Autocomplete结合Formik自定义选项点击无响应问题排查
问题描述
使用Formik的setFieldValue结合自定义renderOption实现Material UI Autocomplete组件,采用自定义input字段而非默认TextField。当前选项筛选功能正常,但点击下拉选项时无任何响应,Chrome断点未捕捉到点击选项的触发逻辑。
核心错误点及修复方案
1. renderOption未传递关键props
MUI Autocomplete的renderOption参数提供的props包含组件内部的点击事件、选中状态等核心逻辑,自定义渲染选项时必须将这些props传递给根元素,否则点击无法触发组件的选中回调。
修复后FilterDropdown的renderOption代码:
renderOption={(props, option: DropdownOptionProps) => { const { label, mixin } = option return dropdownDataLayout // 将Autocomplete的props与自定义mixin合并传递给布局组件 ? createElement(dropdownDataLayout, { ...props, ...(mixin as Record<string, string>) }) : label && ( <div {...props} className="flex flex-col w-full"> <Translate label={label} /> <Divider className="!my-2" /> </div> ) }}
2. setFieldValue传递无效引用
在transfer-assets.tsx中,传递给FilterDropdown的setFieldValue={() => setFieldValue}是一个返回函数的嵌套函数,而非直接传递Formik的setFieldValue方法,导致组件内部无法正确触发Formik的状态更新。
修复后FilterDropdown调用代码:
<FilterDropdown data={pensionFundsData} dropdownDataLayout={TransferAssetsLayout} selectFieldLabel="USM-PortfolioEdit:TransferAssets.InstitutionName" fieldValue={'pension_fund_name'} buttonLabel={pension_fund_name} setFieldValue={setFieldValue} // 直接传递Formik的setFieldValue方法 errors={errors.pension_fund_name} />
3. 自定义input未正确关联Autocomplete参数
原FilterDropdownInput仅传递了params.inputProps,未完整关联Autocomplete所需的其他属性(如ref、InputProps等),可能导致组件内部状态不同步。同时自定义布局组件中无需手动添加onClick,Autocomplete的onChange会处理选中逻辑,手动添加会引发冲突。
修复后TransferAssetsLayout代码:
// 接收Autocomplete传递的props并展开到根元素 const TransferAssetsLayout = (props: any & Record<string, string>) => ( <div {...props} className="funds flex flex-col w-full cursor-pointer" > <p className="text-text-primary typo-regular-300 px-2">{props.name}</p> {props.recipient && ( <p className={clsx( classes.italic, 'text-text-secondary typo-regular-200 px-2 pb-1', )} > {props.recipient} </p> )} <p className={clsx( classes.italic, 'text-text-secondary typo-regular-200 px-2 pb-1', )} > {`${props.address}, ${props.zip_code} ${props.location}`} </p> <Divider className="!m-0" /> </div> )
修复后FilterDropdownInput代码:
export const FilterDropdownInput = ({ params, label, error, }: FilterDropdownProps) => { const { t } = useTranslation() return ( <TextField {...params} label={t(label)} placeholder={t('common:Field.Search', 'Enter search term')} error={!!error} helperText={error} inputProps={{ ...params.inputProps }} /> ) }
内容的提问来源于stack exchange,提问作者user5618326

