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

使用Material-UI与React Hook Form时无法记录amount字段值求助

问题:React-Hook-Form提交表单时无法获取amount文本框的值

我使用React-Hook-Form、Zod和Material-UI创建TextField组件,提交表单时控制台无法输出amount文本框的值,请问我的代码是否存在遗漏?

代码示例

function App() {
  const schema = zod.object({
    amount: zod.string().optional()
  });

  type FormData = zod.infer<typeof schema>;

  const resolver = zodResolver(schema);

  const {
    handleSubmit,
    formState: { errors },
    register
  } = useForm<FormData>({
    mode: "onSubmit",
    resolver
  });

  const onSubmit = (data: any) => console.log(data);
  console.log(errors);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Stack spacing={2} direction="row" alignItems="center">
        <CurrencyInput
          label="Amount"
          type="text"
          {...register("amount")}
          fullWidth
        />
        <Button type="submit" variant="contained" fullWidth>
          Submit
        </Button>
      </Stack>
    </form>
  );
}

问题原因

核心问题出在自定义的CurrencyInput组件没有正确对接React-Hook-Form的register方法。React-Hook-Form的register会返回onChange、value、name等关键props,这些需要传递给组件内部的原生input元素(或Material-UI TextField的底层input)才能实现值的监听和同步。如果CurrencyInput没有转发这些props,React-Hook-Form就无法捕获输入值。

解决方案

修改CurrencyInput组件,确保将接收到的所有props(包括register返回的内容)传递给内部的Material-UI TextField:

// 正确的CurrencyInput组件写法示例
import TextField from '@mui/material/TextField';

const CurrencyInput = ({ label, ...props }) => {
  return (
    <TextField
      label={label}
      {...props} // 必须转发register返回的props给TextField
      variant="outlined"
    />
  );
};

如果CurrencyInput有自定义的数值格式化逻辑,需要手动同步value和onChange:

const CurrencyInput = ({ label, value, onChange, ...props }) => {
  // 自定义格式化逻辑示例
  const formatValue = (val) => {
    return val ? `$${val}` : '';
  };

  const handleInputChange = (e) => {
    // 移除格式,传递原始值给React-Hook-Form
    const rawValue = e.target.value.replace(/^\$/, '');
    onChange(rawValue);
  };

  return (
    <TextField
      label={label}
      value={formatValue(value)}
      onChange={handleInputChange}
      {...props}
    />
  );
};

另外,虽然你的Zod schema将amount设为optional,但只有当组件正确传递值时,该字段才会出现在提交的data对象中。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:22:06