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

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>
  );
}

原理说明

  1. 添加name属性:react-router-dom的<Form>依赖控件的name属性构建FormData,因此必须给每个与useForm字段对应的控件添加同名name。
  2. 保留受控绑定:继续使用value={form.values.xxx}和onChange={form.setFieldValue},确保useForm能正常跟踪字段值、触发实时验证逻辑。
  3. 前端验证拦截:通过form.validate()在提交前触发完整验证,验证失败时阻止表单提交到Action,保证只有合法数据才会进入后端处理流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 02:20:59