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

React状态不立即更新致登录需双击跳转,求技术解决方案

问题原因分析

你遇到的两次点击才跳转的问题,核心是React的状态更新是异步批量处理的:在handleAuth中调用setIsLogged(true)和setCurrentUser后,组件不会立刻更新状态,此时立刻调用navigateAfterLogin,函数内读取的还是更新前的isLogged(false)和currentUser(初始空对象),所以第一次点击无法触发跳转;第二次点击时状态已完成更新,才能正确执行导航逻辑。

不需要用useRef替代state,只需调整导航逻辑即可解决问题。


解决方案

推荐直接使用loginCheck返回的用户数据进行导航,无需等待state异步更新,逻辑更简洁可靠:

修改后的完整代码

import { Route, Routes, Link} from "react-router-dom";
import Home from "./pages/Home";
import Login from "./pages/Login";
import Profile from "./pages/Profile";
import { useNavigate } from "react-router-dom";
import { useState} from 'react';

function App() {
  const [currentUser, setCurrentUser] = useState({id:null, username:null, password:null});
  const [userInput, setUserInput] = useState("");
  const [passInput, setPassInput] = useState("");
  const [isLogged, setIsLogged] = useState(false);

  const navigate = useNavigate();

  const data = [
    { id: 1, username: "jane", password: "1234",isAdmin:true },
    { id: 2, username: "jack", password: "1234", isAdmin: false },
    { id: 3, username: "john", password: "1234" , isAdmin:false},
    { id: 4, username: "elizabeth", password: "1234", isAdmin: false}
  ];
  
  const loginCheck = (username, password) => {
    console.log("logincheck function working");
    const getUserData = data.find(user => user.username === username && user.password === password);  
    console.log(getUserData);
    if(getUserData){
      console.log(`${getUserData.username} logged in`);
      return getUserData;
    } else {
      console.log("user not found");
      return null;
    }
  };

  const handleAuth = () => {
    console.log("handlesubmit function working");
    const gelen = loginCheck(userInput, passInput);

    if (gelen) {
      // 更新状态
      setIsLogged(true);
      setCurrentUser(gelen);
      // 直接用校验返回的用户数据导航
      navigateAfterLogin(gelen);
    } else {
      setIsLogged(false);
      setCurrentUser({id:null, username:null, password:null});
      navigateAfterLogin(null);
    }
  }

  // 导航函数接收用户数据参数,不再依赖组件state
  const navigateAfterLogin = (user) => {
    console.log("navigation function working.");
    if (user) {
      console.log("redirecting to profile page");
      const timer = setTimeout(() => {
        navigate(`/users/${user.username}`, {
          state: {
            id: user.id, 
            username: user.username,
            isAdmin: user.isAdmin
          }
        });
      }, 3000);
      return () => clearTimeout(timer);
    } else {
      console.log("redirecting to login page");
      navigate(`/login`);
    }
  };

  return (
    <div>
      <h1>Navbar</h1>
      <Link to="/">Home</Link>
      <Link to="login">Login</Link>
      <input name="username" type="text" placeholder="username" onChange={(e)=> setUserInput(e.target.value)}  /> 
      <input name="password" type="password" placeholder="password" onChange={(e)=> setPassInput(e.target.value)}/>
      <button onClick={handleAuth} type="submit">Login</button>
      <div style={{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"}}>
        <h1>
          <label>hesabınıza giriş yapın</label>
        </h1>
      </div>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="login" element={<Login />} />
        <Route path="users/:id" element={<Profile/>} />
        <Route path="*" element={<h1>404 not found</h1>} />
      </Routes>
    </div>
  );
}

export default App;

备选方案:通过useEffect监听状态导航

如果一定要依赖state变化触发导航,可以使用useEffect监听状态更新,此时需要移除handleAuth中对navigateAfterLogin的调用:

import { useEffect } from 'react';

// ... 其他代码保持不变

useEffect(() => {
  if (isLogged && currentUser.id) {
    const timer = setTimeout(() => {
      navigate(`/users/${currentUser.username}`, {
        state: {
          id: currentUser.id, 
          username: currentUser.username,
          isAdmin: currentUser.isAdmin
        }
      });
    }, 3000);
    return () => clearTimeout(timer);
  } else if (!isLogged && !currentUser.id) {
    navigate('/login');
  }
}, [isLogged, currentUser, navigate]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 16:50:42