使用shadcn库时React表单无法提交的问题求助
问题:Vite+React集成shadcn后表单提交无响应
使用Vite开发React应用,集成shadcn/ui库后表单完全无法提交,但未使用该库时表单功能正常。相关组件代码如下:
Register组件代码
import React from "react"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import axios from "axios"; import { useNavigate } from "react-router-dom"; import { Form } from "@/components/ui/form"; import LinkButton from "@/components/Button"; import Navbar from "@/components/Navbar"; import RegisterForm from "@/components/RegisterForm"; const schema = z .object({ username: z.string().min(2), password: z.string().min(8), confirmPassword: z.string().min(8), email: z.string().email(), }) .refine((data) => data.password === data.confirmPassword, { message: "Passwords don't match", path: ["confirmPassword"], }); export const Register = () => { const navigate = useNavigate(); const methods = useForm({ resolver: zodResolver(schema), defaultValues: { email: "", username: "", password: "", confirmPassword: "", } }) const { handleSubmit, control, formState: { isSubmitting } } = methods; const onSubmit = async (values) => { console.log("Form values:", values); const { username, password, email } = values; try { console.log("Attempting to register user..."); const response = await axios.post("/api/auth/register", { username, email, password, }); console.log(response.data); navigate("/login"); } catch (error) { console.error("Error during registration:", error); } }; console.log("Render Register component"); return ( <div> <Navbar /> <div className="flex justify-center items-center h-screen"> <Form {...methods}> <form onSubmit={handleSubmit(onSubmit)} className="space-y-6 p-4 xl:w-1/2 md:w-1/2 sm:w-1/2 xs:w-full xs:p-5 shadow-md" > <RegisterForm name="username" label="Username" placeholder="Username" inputType="username" formControl={control}/> <RegisterForm name="email" label="Email" placeholder="Email" inputType="email" formControl={control}/> <RegisterForm name="password" label="Password" placeholder="Password" inputType="password" formControl={control}/> <RegisterForm name="confirmPassword" label="Confirm Password" placeholder="Confirm Password" inputType="password" formControl={control}/> <LinkButton type="submit" className="w-full bg-bg-btn-prm" disabled={isSubmitting} > {isSubmitting ? "Loading..." : "Register"} </LinkButton> </form> </Form> </div> </div> ); };
RegisterForm组件代码
import React from 'react'; import { FormControl, FormField, FormItem, FormLabel, FormMessage } from './ui/form'; import { Input } from './ui/input'; const RegisterForm = React.memo(({ name, label, placeholder, inputType = 'text', formControl }) => { console.log(`Rendering field: ${name}`); return ( <FormField control={formControl} name={name} render={({ field }) => ( <FormItem> <FormLabel>{label}</FormLabel> <FormControl> <Input placeholder={placeholder} type={inputType} {...field} /> </FormControl> <FormMessage /> </FormItem> )} /> ); }); export default RegisterForm;
问题排查与解决方案
核心原因
shadcn/ui的<Form>组件已经封装了react-hook-form的上下文和表单处理逻辑,你在它内部嵌套原生<form>标签,导致提交事件被拦截,无法正确触发handleSubmit。
修复方案
移除原生<form>标签,将提交逻辑直接绑定到shadcn的<Form>组件上,调整后的Register组件核心部分如下:
// ...其他代码不变 return ( <div> <Navbar /> <div className="flex justify-center items-center h-screen"> <Form {...methods} onSubmit={handleSubmit(onSubmit)} className="space-y-6 p-4 xl:w-1/2 md:w-1/2 sm:w-1/2 xs:w-full xs:p-5 shadow-md" > <RegisterForm name="username" label="Username" placeholder="Username" inputType="username" formControl={control}/> <RegisterForm name="email" label="Email" placeholder="Email" inputType="email" formControl={control}/> <RegisterForm name="password" label="Password" placeholder="Password" inputType="password" formControl={control}/> <RegisterForm name="confirmPassword" label="Confirm Password" placeholder="Confirm Password" inputType="password" formControl={control}/> <LinkButton type="submit" className="w-full bg-bg-btn-prm" disabled={isSubmitting} > {isSubmitting ? "Loading..." : "Register"} </LinkButton> </Form> </div> </div> );
额外检查项
- 确认
LinkButton组件实际渲染为原生<button>元素,且type="submit"属性未被覆盖 - 验证shadcn/ui的Form组件版本与react-hook-form版本兼容
内容的提问来源于stack exchange,提问作者vlad_dejan
相关产品推荐
相关产品推荐

