使用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
相关产品推荐
相关产品推荐

