react-router-dom Actions与Mantine useForm冲突问题及方案咨询
Mantine useForm 与 react-router-dom Actions 优雅结合方案
问题描述
使用Mantine的Authentication Form组件时,将原生form替换为react-router-dom的<Form>后,点击Register按钮时request.formData()无法获取表单数据;给输入框添加name属性能解决数据收集问题,但会导致Mantine useForm的表单验证功能失效。需要找到两者兼容的优雅实现方式。
解决方案
核心是给表单控件添加对应name属性的同时,保留Mantine useForm的受控绑定逻辑,既满足react-router-dom收集FormData的要求,又不破坏useForm的验证机制。
修改步骤及代码示例
以下是修改后的authForm.tsx关键部分:
export default function AuthenticationForm(props: PaperProps) { const [type, toggle] = useToggle(["login", "register"]); const form = useForm({ initialValues: { email: "", name: "", password: "", terms: true, }, validate: { email: (val) => (/^\S+@\S+$/.test(val) ? null : "Invalid email"), password: (val) => val.length <= 6 ? "Password should include at least 6 characters" : null, }, }); // 提交前先执行前端验证 const handleSubmit = async (event: React.FormEvent) => { const isValid = await form.validate(); if (!isValid) { event.preventDefault(); // 验证失败时阻止表单提交到Action } }; return ( <Paper radius="md" p="xl" withBorder {...props}> {/* 其他固定内容省略 */} <Form method="post" onSubmit={handleSubmit}> <Stack> {type === "register" && ( <TextInput name="name" // 添加与useForm字段对应的name属性 label="Name" placeholder="Your name" value={form.values.name} onChange={(event) => form.setFieldValue("name", event.currentTarget.value) } radius="md" /> )} <TextInput name="email" // 添加name属性 required label="Email" placeholder="hello@mantine.dev" value={form.values.email} onChange={(event) => form.setFieldValue("email", event.currentTarget.value) } error={form.errors.email && "Invalid email"} radius="md" /> <PasswordInput name="password" // 添加name属性 required label="Password" placeholder="Your password" value={form.values.password} onChange={(event) => form.setFieldValue("password", event.currentTarget.value) } error={ form.errors.password && "Password should include at least 6 characters" } radius="md" /> {type === "register" && ( <Checkbox name="terms" // 添加name属性 label="I accept terms and conditions" checked={form.values.terms} onChange={(event) => form.setFieldValue("terms", event.currentTarget.checked) } /> )} </Stack> {/* 其他固定内容省略 */} </Form> </Paper> ); }
原理说明
- 添加name属性:react-router-dom的
<Form>依赖控件的name属性构建FormData,因此必须给每个与useForm字段对应的控件添加同名name。 - 保留受控绑定:继续使用
value={form.values.xxx}和onChange={form.setFieldValue},确保useForm能正常跟踪字段值、触发实时验证逻辑。 - 前端验证拦截:通过
form.validate()在提交前触发完整验证,验证失败时阻止表单提交到Action,保证只有合法数据才会进入后端处理流程。
内容的提问来源于stack exchange,提问作者Liondancer
相关产品推荐
相关产品推荐

