如何实现MUI v6 Timepicker与Formik集成?值绑定失败求助
解决MUI TimePicker与Formik集成时initialValues绑定失效问题
问题核心是MUI TimePicker的props与Formik Field组件的props不兼容,直接传递{...field}无法正确同步值,导致提交时取不到mondayFrom字段。以下是修复方案:
修复步骤
- 移除Formik的
Field组件,直接通过Formik提供的values和setFieldValue手动绑定TimePicker - 处理TimePicker的
onChange事件,将返回的Date对象转换为目标字符串格式(如HH:mm) - 初始化值时,将空字符串改为
null,因为TimePicker仅接受Date | null类型的value
修改后的完整代码
import { useState } from 'react'; import { Formik, Form } from 'formik'; import { TimePicker } from '@mui/x-date-pickers/TimePicker'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; type RegisterFormProps = { mondayFrom: string | null; mondayTo: string | null; }; export default function YourComponent() { const [initialValues, setInitialValues] = useState<RegisterFormProps>({ mondayFrom: null, mondayTo: null, }); const onSubmit = async (values: RegisterFormProps) => { console.log({ values }); // 现在可正常获取mondayFrom的值 }; return ( <LocalizationProvider dateAdapter={AdapterDateFns}> <Formik initialValues={initialValues} enableReinitialize onSubmit={onSubmit}> {({ values, handleSubmit, setFieldValue }) => ( <Form onSubmit={handleSubmit}> <TimePicker value={values.mondayFrom ? new Date(`1970-01-01T${values.mondayFrom}`) : null} onChange={(newValue) => { if (newValue) { const formattedTime = newValue.toTimeString().slice(0, 5); // 转换为HH:mm格式 setFieldValue('mondayFrom', formattedTime); } else { setFieldValue('mondayFrom', null); } }} ampm={false} format="HH:mm" slotProps={{ textField: { label: "Monday From", size: "small", fullWidth: true, }, }} /> {/* mondayTo的TimePicker可复用相同逻辑 */} <button type="submit">提交</button> </Form> )} </Formik> </LocalizationProvider> ); }
关键说明
- 值类型匹配:TimePicker的
value需为Date或null,因此从Formik取值时要将字符串转为Date对象,空值设为null - onChange同步:将TimePicker返回的Date对象格式化为
HH:mm字符串,再通过setFieldValue同步到Formik状态 - 依赖组件:必须用
LocalizationProvider包裹TimePicker,否则组件无法正常工作
若需添加表单验证,可集成Yup扩展逻辑:
import * as Yup from 'yup'; const validationSchema = Yup.object().shape({ mondayFrom: Yup.string().required('请选择开始时间'), }); // 在Formik中传入validationSchema <Formik initialValues={initialValues} enableReinitialize onSubmit={onSubmit} validationSchema={validationSchema} > {/* 原有代码 */} </Formik>
内容的提问来源于stack exchange,提问作者Profer
相关产品推荐
相关产品推荐

