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

React Router结合UseContext状态同步异常问题求助

问题描述

我有Login和Dashboard组件,通过AppContext存储isLogin状态和setIsLogin方法。点击Login组件的登录按钮后,Login组件里的isLogin状态已经更新,但Dashboard组件中的状态没有同步更新;不使用React Router时功能完全正常。

相关代码

App组件

import "./App.scss";
import React from "react";
import Card from "./Component/Card/Card";
import List from "./Component/list/list";
import axios from "axios";
import Header from "./Component/Header/Header";
import Login from "./pages/Login";
import Dashboard from "./pages/Dashboard";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";

export const AppContext = React.createContext();
function App() {
  const [isLogin, setIsLogin] = React.useState(false);
  const [products, setProducts] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  return (
    <div className="App">
      <Header></Header>
      <AppContext.Provider value={{ isLogin, setIsLogin }}>
        <Routes>
          <Route path="/" element={<Login />} />
          <Route path="/dash" element={<Dashboard />} />
        </Routes>
      </AppContext.Provider>  
     </div>
  );
}

export default App;

Login组件

import React, { useState, useContext } from "react";
import { LoginContext } from "../LogincContext";
import { AppContext } from "../App";
const Login = () => {
  const { isLogin, setIsLogin } = useContext(AppContext);

  const handleLogin = () => {
    setIsLogin(true);
    console.log("Login", isLogin);
  };

  return (
    <div>
      <input type="email" placeholder="Email" />
      <input type="password" placeholder="Password" />
      <button onClick={handleLogin}>Log in</button>
    </div>
  );
};
export default Login;

Dashboard组件

import React from "react";
import { AppContext } from "../App";
const Dashboard = () => {
  const { isLogin } = React.useContext(AppContext);

  console.log(isLogin);

  return (
    <div>
      {isLogin ? (
        <div>Welcome to the store!</div>
      ) : (
        <div>Please log in to access the store.</div>
      )}
    </div>
  );
};

export default Dashboard;

问题原因

  1. 登录后未导航到Dashboard页面:Login组件更新isLogin状态后,Dashboard组件没有被触发挂载/重新渲染,因此它读取的仍是初始的false状态。
  2. 状态更新的异步特性:setIsLogin(true)是异步操作,立即调用console.log(isLogin)会打印更新前的旧值,这是React的正常行为。

解决方案

步骤1:在Login组件中添加导航逻辑

使用react-router-dom提供的useNavigate钩子,登录成功后跳转到Dashboard页面,触发组件重新挂载以读取最新状态。

修改后的Login组件代码

import React, { useContext, useEffect } from "react";
import { AppContext } from "../App";
import { useNavigate } from "react-router-dom";

const Login = () => {
  const { isLogin, setIsLogin } = useContext(AppContext);
  const navigate = useNavigate();

  const handleLogin = () => {
    setIsLogin(true);
    // 登录成功后跳转到Dashboard
    navigate("/dash");
  };

  // 监听isLogin状态变化,打印最新值
  useEffect(() => {
    console.log("Login组件当前isLogin状态:", isLogin);
  }, [isLogin]);

  return (
    <div>
      <input type="email" placeholder="Email" />
      <input type="password" placeholder="Password" />
      <button onClick={handleLogin}>Log in</button>
    </div>
  );
};
export default Login;

说明

  • 导航到/dash后,Dashboard组件会重新挂载,此时通过useContext读取的就是更新后的isLogin状态。
  • 使用useEffect监听isLogin变化,可以正确获取到异步更新后的最新状态,避免旧值打印问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 09:03:25