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

React中调用useState的setState后history.push无法正常跳转怎么办

问题根因
  • 你的App组件将加载判断放在了BrowserRouter外层,当isLoading被设为true时,整个路由树(包括BrowserRouter、上下文Provider、所有路由组件)都会被直接卸载,仅渲染加载动画。
  • 登录提交逻辑中先执行setIsLoading(true),会立刻触发App重渲染卸载路由结构,此时Login组件也被销毁,后续调用的history实例已经对应被卸载的路由,push操作自然无法生效。即使后续再将isLoading设为false,重新渲染出来的是全新的路由实例,之前的跳转指令已经失效。
  • 额外问题:你在App中解构的setUserContext并未在GetUser自定义Hook中返回,运行时会抛出未定义错误,需要删除该字段。
解决方案

提供两种可直接落地的修改方式:

方案1:将路由和上下文移到最外层,加载判断放在内部

修改App.tsx结构,保证BrowserRouter永远不会被卸载:

// App.tsx
function App() {
  const { user, setUser, isLoading, setIsLoading } = GetUser();

  return (
    <BrowserRouter>
      <UserContext.Provider value={{isLoading, user, setUser, setIsLoading}}>
        {isLoading ? (
          <div style={spinnerStyle}>
            <ClipLoader color="red" loading={isLoading.valueOf()} size={150} />
          </div>
        ) : (
          <Switch>
            <Route exact path="/">
              <Login/>
            </Route>
            <AuthRoute exact path="/Dashboard" component={Dashboard}></AuthRoute>
          </Switch>
        )}
      </UserContext.Provider>
    </BrowserRouter>
  );
}

方案2:全局加载层采用浮层形式,不卸载路由结构

如果需要在页面切换、操作过程中都能展示全局加载,可将加载组件设为固定定位浮层,和路由视图平级共存:

// App.tsx
function App() {
  const { user, setUser, isLoading, setIsLoading } = GetUser();

  return (
    <BrowserRouter>
      <UserContext.Provider value={{isLoading, user, setUser, setIsLoading}}>
        {/* 全局加载浮层,不影响下层路由结构 */}
        {isLoading && (
          <div style={{
            ...spinnerStyle,
            position: 'fixed',
            top: 0,
            left: 0,
            width: '100vw',
            height: '100vh',
            zIndex: 9999,
            background: '#fff'
          }}>
            <ClipLoader color="red" loading={isLoading.valueOf()} size={150} />
          </div>
        )}
        <Switch>
          <Route exact path="/">
            <Login/>
          </Route>
          <AuthRoute exact path="/Dashboard" component={Dashboard}></AuthRoute>
        </Switch>
      </UserContext.Provider>
    </BrowserRouter>
  );
}

修改完成后放开Login.tsx中history.push("/Dashboard")的注释即可正常跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 16:18:03