ReactJS:使用Formik自定义组件时出现Cannot read properties of undefined (reading 'type')错误
问题原因
这个报错的核心是Formik的field.onChange和React Typeahead的onChange回调格式不兼容:
- Formik的
field.onChange默认期望接收标准React合成事件对象,它会尝试读取事件的target.type属性来处理表单值更新; - 但React Typeahead的
onChange返回的是选中的值(或值数组),并非事件对象。当Formik试图读取这个值的type属性时,自然会抛出"Cannot read properties of undefined"的错误。
解决方案
你需要在自定义AutoComplete组件里手动适配两者的回调逻辑,用Formik提供的form.setFieldValue方法来更新表单值,而不是直接传递field.onChange给Typeahead。修改后的组件代码如下:
const AutoComplete = ({ field, form, ...props }) => { // 重写onChange,适配Typeahead的返回值格式 const handleChange = (selected) => { // 单选场景取数组第一个元素,多选则直接传数组 const value = props.multiple ? selected : selected[0]; // 调用Formik的setFieldValue更新对应字段 form.setFieldValue(field.name, value); }; // 将Formik存储的单个值转换为Typeahead要求的数组格式 const typeaheadValue = Array.isArray(field.value) ? field.value : field.value ? [field.value] : []; return ( <Typeahead {...props} value={typeaheadValue} onChange={handleChange} /> ); };
额外说明
- 值格式适配:Typeahead的
value属性要求是数组类型,但Formik在单选场景下存储的是单个值,所以需要把单个值包装成数组; - 多选场景兼容:如果你的组件需要支持多选,只需确保Formik对应字段存储的是数组,同时去掉
selected[0]的取值逻辑即可; - 放弃直接传递field属性:因为我们已经手动处理了值更新逻辑,不需要再把
field里的onChange等属性传给Typeahead。
修改后,选择Typeahead选项时就会通过setFieldValue正确更新Formik的表单状态,不会再触发类型错误了。
内容的提问来源于stack exchange,提问作者Code Guru
相关产品推荐
相关产品推荐

