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

React SSR水化失败求助:登录后刷新Dashboard页面报错

解决Hydration失败错误的方案

问题根源

你的 hydration 错误核心是服务器端渲染时无法访问浏览器的 localStorage,导致服务器生成的HTML和客户端首次渲染内容不匹配,具体出在两处:

  • App.jsx 中直接在 useState 初始值里调用依赖 localStorage 的 getStoredUsers
  • Dashboard.jsx 的客户端逻辑仍有不严谨的地方

修复步骤

1. 修正 App.jsx 的初始状态获取

把依赖 localStorage 的初始状态移到 useEffect 中,避免服务器端执行时出错:

import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";

export default function App() {
  const navigate = useNavigate();

  // 初始状态设为空数组,不在 useState 里直接调用 localStorage
  const [users, setUsers] = useState([]);
  const [loginData, setLoginData] = useState({ username: "", password: "" });
  const [signupData, setSignupData] = useState({ username: "", password: "" });
  const [error, setError] = useState("");
  const [isSignupOpen, setIsSignupOpen] = useState(false);

  // 在 useEffect 中获取 localStorage 数据,确保只在客户端执行
  useEffect(() => {
    const getStoredUsers = () => {
      try {
        return JSON.parse(localStorage.getItem("users")) || [];
      } catch {
        return [];
      }
    };
    setUsers(getStoredUsers());
  }, []);

  useEffect(() => {
    localStorage.setItem("users", JSON.stringify(users));
  }, [users]);

  // 以下 handleLogin、handleSignup 及返回的 JSX 保持不变
}

2. 优化 Dashboard.jsx 的客户端渲染逻辑

确保所有依赖 localStorage 和路由跳转的逻辑都在客户端完成,同时避免服务器端渲染出不一致内容:

import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";

export default function Dashboard() {
  const navigate = useNavigate();
  const [loggedInUser, setLoggedInUser] = useState(null);
  const [isMounted, setIsMounted] = useState(false);

  useEffect(() => {
    setIsMounted(true);
    const checkAuth = () => {
      const storedUser = localStorage.getItem("loggedInUser");
      if (storedUser) {
        try {
          const parsedUser = JSON.parse(storedUser);
          setLoggedInUser(parsedUser?.username || "Guest");
        } catch (error) {
          console.error("Error parsing logged-in user:", error);
          navigate("/");
        }
      } else {
        navigate("/");
      }
    };
    checkAuth();
  }, [navigate]);

  // 服务器端和未挂载时返回统一的空内容,避免不匹配
  if (!isMounted) {
    return null;
  }

  // 以下返回的 JSX 保持不变
}

关键注意点

  • 所有依赖浏览器API(localStorage、window等)的逻辑,必须放在 useEffect 中执行,确保只在客户端运行
  • 服务器端渲染时,组件初始状态要和客户端首次渲染的初始状态保持一致,避免 hydration 不匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:50:16