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

Typescript环境下结合React Hook Form使用MUI DatePicker组件报错求助

问题原因

    1. Controller组件未接收校验规则:你定义了options属性存放校验规则,但没有传给Controller的rules属性,导致配置的必填等校验不生效。
    1. 丢弃了field的ref属性:你在解构field的时候把ref单独拎出来丢弃,DatePicker需要通过ref绑定输入框实现焦点控制、弹窗定位等逻辑,缺失会导致功能异常。
    1. 自定义renderInput写法错误:调用时传入的renderInput没有使用DatePicker注入的输入框参数,还额外传入了多余的register属性,使用Controller管理表单状态的场景下不需要手动调用register注册字段,会导致状态冲突。
    1. 未透传错误状态:组件接收了error属性,但没有传递给最终渲染的TextField,无法显示错误提示样式和文案。
    1. 类型过滤问题:你的ENOFieldOverrides类型中包含了renderInput字段,定义ENODateFieldProps时用Omit过滤ENOFieldOverrides会导致renderInput属性被组件拒绝接收,即使你调用时传入了也不会生效,这就是你截图报错的直接原因:DatePicker没有收到必填的renderInput属性。

解决方案

第一步:修改ENODateField组件代码

import DatePicker, { DatePickerProps } from "@mui/lab/DatePicker";
import React from "react";
import { Control, Controller, FieldValues } from "react-hook-form";
import { ENOFieldOverrides, ENOFieldProps } from "./EnoFieldUtils";
import ENOTooltip from "./ENOTooltip";
import { makeStyles } from "@mui/styles";
import AdapterDateFns from "@mui/lab/AdapterDateFns";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import TextField from "@mui/material/TextField";

export interface ENODateFieldProps<T extends FieldValues>
    extends Omit<ENOFieldProps<T>, "register">,
        // 排除ENOFieldOverrides中的renderInput,避免过滤掉必填属性
        Omit<DatePickerProps, Exclude<ENOFieldOverrides, "renderInput"> | "value" | "onChange"> {
    control: Control<T, object>;
}

const useStyles = makeStyles({
    fullWidth: {
        width: "100%",
    },
});

export default function ENODateField<T extends FieldValues>({
    name,
    control,
    options,
    error,
    tooltipText,
    ...rest
}: ENODateFieldProps<T>) {
    const classes = useStyles();

    return (
        <ENOTooltip text={tooltipText}>
            <LocalizationProvider dateAdapter={AdapterDateFns}>
                <Controller
                    name={name}
                    control={control}
                    // 把校验规则传给Controller的rules属性
                    rules={options}
                    render={({ field }) => (
                        <DatePicker
                            className={classes.fullWidth}
                            // 完整透传field属性,包含ref、value、onChange等
                            {...field}
                            {...rest}
                            // 统一处理错误状态透传,优先使用用户自定义的renderInput
                            renderInput={(params) =>
                                rest.renderInput ? (
                                    rest.renderInput({
                                        ...params,
                                        error: !!error,
                                        helperText: error?.message,
                                    })
                                ) : (
                                    <TextField
                                        {...params}
                                        error={!!error}
                                        helperText={error?.message}
                                    />
                                )
                            }
                        />
                    )}
                />
            </LocalizationProvider>
        </ENOTooltip>
    );
}

第二步:修改调用代码

如果不需要自定义输入框,直接简化调用即可:

<DateField<ReceptionInvoice>
  label="Issue Date"
  control={control}
  name="invoiceDate"
  options={{
    required: "This field is required",
  }}
  error={errors.invoiceDate}
/>

如果需要自定义TextField的其他属性,按如下写法传入renderInput即可:

<DateField<ReceptionInvoice>
  label="Issue Date"
  control={control}
  name="invoiceDate"
  options={{
    required: "This field is required",
  }}
  error={errors.invoiceDate}
  renderInput={(params) => (
    <TextField
      {...params}
      variant="outlined"
      size="small"
      // 其他自定义TextField属性
    />
  )}
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:24:03