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

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

关键说明

  1. 显式指定type="email"和type="password",彻底避免浏览器自动推断带来的DOM差异。
  2. 添加defaultValues确保useForm在服务端和客户端的初始表单状态完全一致,进一步消除Hydration风险。
  3. 为Yup验证规则添加自定义错误信息,提升表单的用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:50:44