如何让Formik在验证失败时自动聚焦MUI X DatePicker组件?
问题:Formik验证失败时自动聚焦MUI X DatePicker组件
我在Formik中使用必填的MUI X DatePicker组件,代码如下:
<DatePicker name={field.name} label={field.title} onChange={(newValueRaw: moment.Moment) => { setFieldValue(field.name, newValueRaw); }} defaultValue={moment.utc(field.value)} disabled={!field.editable} slotProps={{ textField: { required: field.validation?.required } }} />
点击提交按钮时,若因未设置日期导致验证失败,该DatePicker组件不会自动聚焦。如何实现Formik在验证失败时自动聚焦该组件?
依赖版本:
- formik: ^2.4.6
- @mui/x-date-pickers: ^7.20.0
- react: ^18.3.1
解决方案
要实现验证失败时自动聚焦DatePicker,核心是结合Formik的提交/错误状态与MUI组件的引用,手动触发聚焦操作,具体步骤如下:
1. 绑定DatePicker内部输入框的引用
MUI X DatePicker的聚焦实际作用于其内部的TextField组件,因此需要通过slotProps将React的useRef绑定到TextField上。
2. 监听Formik的提交状态与错误
利用useEffect监听Formik的isSubmitting状态和errors对象,当提交触发且目标字段存在错误时,调用输入框的focus()方法。
完整实现代码
import { useRef, useEffect } from 'react'; import { useFormikContext } from 'formik'; import { DatePicker } from '@mui/x-date-pickers'; import moment from 'moment'; const FormikDatePicker = ({ field }) => { const { isSubmitting, errors, setFieldValue } = useFormikContext(); const datePickerInputRef = useRef(null); useEffect(() => { // 提交过程中若当前字段验证失败,自动聚焦 if (isSubmitting && errors[field.name]) { datePickerInputRef.current?.focus(); } }, [isSubmitting, errors, field.name]); return ( <DatePicker name={field.name} label={field.title} onChange={(newValueRaw) => setFieldValue(field.name, newValueRaw)} defaultValue={moment.utc(field.value)} disabled={!field.editable} slotProps={{ textField: { required: field.validation?.required, ref: datePickerInputRef // 将引用绑定到内部TextField } }} /> ); }; export default FormikDatePicker;
关键细节说明
- 引用绑定:通过
slotProps.textField.ref将ref指向DatePicker内部的输入框,确保能直接调用聚焦方法。 - 状态监听:
useEffect的依赖数组包含isSubmitting、errors和field.name,确保只有当提交触发且当前字段出错时才执行聚焦。 - Formik上下文:使用
useFormikContext直接获取Formik的状态和方法,避免手动传递props,简化组件逻辑。
注意:确保该自定义DatePicker组件处于Formik组件的上下文范围内,否则useFormikContext无法正常获取数据。
内容的提问来源于stack exchange,提问作者george
相关产品推荐
相关产品推荐

