You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mui-x DateTimePicker v6:如何适配第三方表单库的onChange与onBlur?

MUI-X DateTimePicker v6 与 Formik 等第三方表单库兼容方案

问题描述

MUI-X DateTimePicker v5版本中,onBlur和onChange会返回原生事件对象,可直接配合第三方表单库使用(例如写法:onChange={e => onChange(e.target.value)})。但升级至v6版本后,这两个回调返回的是date或string类型的值,而非事件对象,导致无法直接沿用旧的表单库适配逻辑。

预期效果

希望DateTimePicker能与Formik及其他第三方表单库兼容,调用方式如下:

<DateTimePicker
  value={value}
  onChange={newValue => onChange(new ChangeEvent(...))}
  onBlur={() => onBlur(new FocusEvent('blur'))}
/>

解决方案

1. 直接传递值(推荐方案)

Formik等表单库并不强制要求传入原生事件对象,核心需求是获取更新后的值并同步到表单状态。直接使用Formik的setFieldValue或适配useField钩子即可,写法简洁且符合官方推荐:

方式一:使用setFieldValue

import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import { useFormik } from 'formik';

const MyForm = () => {
  const formik = useFormik({
    initialValues: { date: new Date() },
    onSubmit: (values) => console.log('提交的值:', values),
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <DateTimePicker
        value={formik.values.date}
        onChange={(newValue) => formik.setFieldValue('date', newValue)}
        onBlur={() => formik.handleBlur({ target: { name: 'date' } })}
      />
      <button type="submit">提交表单</button>
    </form>
  );
};

方式二:封装为Formik字段组件

利用Formik的useField钩子封装可复用的DateTimePicker组件,后续直接调用即可:

import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import { useField, useFormikContext } from 'formik';

const FormikDateTimePicker = ({ name, ...restProps }) => {
  const [field] = useField(name);
  const { setFieldValue } = useFormikContext();

  return (
    <DateTimePicker
      {...restProps}
      value={field.value}
      onChange={(newValue) => setFieldValue(name, newValue)}
      onBlur={() => field.onBlur({ target: { name } })}
    />
  );
};

// 使用示例
const MyForm = () => {
  const formik = useFormik({
    initialValues: { appointmentTime: new Date() },
    onSubmit: (values) => console.log(values),
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <FormikDateTimePicker name="appointmentTime" label="预约时间" />
      <button type="submit">提交</button>
    </form>
  );
};

2. 模拟事件对象(适配旧代码)

如果因为历史代码依赖事件对象,必须保持原有回调形式,可以手动构造符合React事件接口的对象:

// 构造适配Formik的ChangeEvent
const createChangeEvent = (name: string, value: Date | null) => ({
  target: { name, value },
  preventDefault: () => {},
  stopPropagation: () => {},
}) as React.ChangeEvent<HTMLInputElement>;

// 构造适配Formik的FocusEvent
const createBlurEvent = (name: string) => ({
  target: { name },
  preventDefault: () => {},
  stopPropagation: () => {},
}) as React.FocusEvent<HTMLInputElement>;

// 使用示例
<DateTimePicker
  value={formik.values.date}
  onChange={(newValue) => formik.handleChange(createChangeEvent('date', newValue))}
  onBlur={() => formik.handleBlur(createBlurEvent('date'))}
/>

内容的提问来源于stack exchange,提问作者RikuS3n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:35:25