最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Hydration failed because the server rendered HTML didn't match the client - Stack Overflow

programmeradmin1浏览0评论

I am trying to prepare a faulty record app but after I successfully log in and direct to dashboard. Pressing F5 gives me "Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used" error. I have tried if(windows !== undefined) and other options but nothing seems to work for me.

App.jsx

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

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

  const getStoredUsers = () => {
    try {
      return JSON.parse(localStorage.getItem("users")) || [];
    } catch {
      return [];
    }
  };

  const [users, setUsers] = useState(getStoredUsers);
  const [loginData, setLoginData] = useState({ username: "", password: "" });
  const [signupData, setSignupData] = useState({ username: "", password: "" });
  const [error, setError] = useState("");
  const [isSignupOpen, setIsSignupOpen] = useState(false);

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

  const handleLogin = (e) => {
    e.preventDefault();
    const user = users.find(
      (u) =>
        u.username === loginData.username && u.password === loginData.password
    );
    if (user) {
      localStorage.setItem("loggedInUser", JSON.stringify(user));
      navigate("/dashboard");
    } else {
      setError("Invalid credentials");
    }
  };

  const handleSignup = (e) => {
    e.preventDefault();
    if (users.some((u) => u.username === signupData.username)) {
      setError("Username already exists");
      return;
    }
    setUsers([...users, signupData]);
    setIsSignupOpen(false);
    setSignupData({ username: "", password: "" });
  };

  return (
    <div className="flex items-center justify-center min-h-screen bg-gray-100">
      <div className="bg-white p-8 rounded shadow-md w-96">
        <h2 className="text-2xl font-bold mb-4">Login</h2>
        {error && <p className="text-red-500">{error}</p>}
        <form onSubmit={handleLogin}>
          <input
            type="text"
            placeholder="Username"
            className="w-full p-2 border rounded mb-2"
            onChange={(e) =>
              setLoginData({ ...loginData, username: e.target.value })
            }
          />
          <input
            type="password"
            placeholder="Password"
            className="w-full p-2 border rounded mb-2"
            onChange={(e) =>
              setLoginData({ ...loginData, password: e.target.value })
            }
          />
          <button
            className="w-full bg-blue-500 text-white p-2 rounded"
            type="submit"
          >
            Login
          </button>
        </form>
        <p className="mt-4 text-center">
          Don't have an account?{" "}
          <button
            className="text-blue-500"
            onClick={() => setIsSignupOpen(true)}
          >
            Sign Up
          </button>
        </p>
      </div>

      {isSignupOpen && (
        <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
          <div className="bg-white p-6 rounded shadow-md w-96">
            <h2 className="text-2xl font-bold mb-4">Sign Up</h2>
            {error && <p className="text-red-500">{error}</p>}
            <form onSubmit={handleSignup}>
              <input
                type="text"
                placeholder="Username"
                className="w-full p-2 border rounded mb-2"
                onChange={(e) =>
                  setSignupData({ ...signupData, username: e.target.value })
                }
              />
              <input
                type="password"
                placeholder="Password"
                className="w-full p-2 border rounded mb-2"
                onChange={(e) =>
                  setSignupData({ ...signupData, password: e.target.value })
                }
              />
              <button
                className="w-full bg-green-500 text-white p-2 rounded"
                type="submit"
              >
                Sign Up
              </button>
            </form>
            <button
              className="mt-4 text-red-500 w-full"
              onClick={() => setIsSignupOpen(false)}
            >
              Cancel
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

Dashboard.jsx

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 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("/");
    }
  }, [navigate]);

  if (!isMounted) {
    return <div>Loading...</div>;
  }

  return (
    <div className="p-6 bg-gray-100 min-h-screen">
      <div className="flex justify-between items-center mb-4">
        <h1 className="text-2xl font-bold">FAULTY RECORD SYSTEM</h1>
        <div className="flex items-center space-x-4">
          <span className="font-semibold">{loggedInUser}</span>
          <button
            onClick={() => {
              localStorage.removeItem("loggedInUser");
              navigate("/");
            }}
            className="bg-red-500 text-white px-4 py-2 rounded"
          >
            Log Off.
          </button>
        </div>
      </div>
    </div>
  );
}
发布评论

评论列表(0)

  1. 暂无评论