在NextJS中使用react-hook-form触发水合错误的问题求助
解决React Hook Form在Next.js中修改字段名触发的Hydration失败错误
你遇到的Hydration错误,核心原因是未显式指定input的type属性时,浏览器会根据字段名自动推断type,导致服务端渲染的DOM和客户端hydrate后的DOM不一致。
比如当你把字段名改为password时,浏览器会自动将对应的input元素的type设为password,但服务端渲染的HTML中该input的type是默认的text,两者DOM结构不匹配,触发Hydration失败错误。而用derp这种非常规字段名时,浏览器不会自动修改type,所以服务端和客户端渲染结果一致,没有问题。
解决方案
显式为每个input指定type属性,确保服务端和客户端渲染的DOM完全一致。同时可添加默认值进一步保证初始状态匹配:
"use client"; import { useForm } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; import * as yup from "yup"; interface IFormInputs { email: string; password: string; } const schema = yup .object({ email: yup.string().email("请输入有效的邮箱").required("邮箱不能为空"), password: yup.string().min(6, "密码长度不能少于6位").required("密码不能为空"), }) .required(); export default function Login() { const { register, handleSubmit, formState: { errors }, } = useForm<IFormInputs>({ resolver: yupResolver(schema), defaultValues: { email: "", password: "", }, }); const onSubmit = (data: IFormInputs) => console.log(data); return ( <form onSubmit={handleSubmit(onSubmit)}> <input type="email" {...register("email")} placeholder="邮箱" /> {errors.email && <p style={{ color: "red" }}>{errors.email.message}</p>} <input type="password" {...register("password")} placeholder="密码" /> {errors.password && <p style={{ color: "red" }}>{errors.password.message}</p>} <input type="submit" value="登录" /> </form> ); }
关键说明
- 显式指定
type="email"和type="password",彻底避免浏览器自动推断带来的DOM差异。 - 添加
defaultValues确保useForm在服务端和客户端的初始表单状态完全一致,进一步消除Hydration风险。 - 为Yup验证规则添加自定义错误信息,提升表单的用户体验。
内容的提问来源于stack exchange,提问作者spetz83
相关产品推荐
相关产品推荐

