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

React页面刷新时如何执行Cognito getSession异步函数获取数据后再渲染?

解决方案

第一步:封装异步getSession方法

首先把Cognito回调形式的getSession封装为Promise版本,方便后续异步逻辑调用:

export const getCurrentSession = async (): Promise<CognitoUserSession | null> => {
  const currentUser = userPool.getCurrentUser();
  if (!currentUser) return null;

  return new Promise((resolve, reject) => {
    currentUser.getSession((err, session) => {
      if (err) return reject(err);
      resolve(session.isValid() ? session : null);
    })
  })
}

第二步:选择适配你技术栈的实现方式

以下两种方案都可以实现「鉴权完成后再渲染页面内容」的需求:

方案1:根组件全局初始化(最常用)

在应用根组件(一般为App.tsx)加全局鉴权loading,等校验完成再渲染路由内容:

import { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { updateToken } from './你的auth切片路径';
import { getCurrentSession } from './cognito工具文件路径';

function App() {
  const [authInitialized, setAuthInitialized] = useState(false);
  const dispatch = useDispatch();
  const token = useSelector(state => state.auth.token);

  useEffect(() => {
    const initAuth = async () => {
      try {
        const session = await getCurrentSession();
        if (session) {
          const accessToken = session.getAccessToken().getJwtToken();
          localStorage.setItem("user", JSON.stringify(accessToken));
          dispatch(updateToken(accessToken));
        }
      } catch (err) {
        // token无效/过期时清空本地存储和redux状态
        localStorage.removeItem("user");
        dispatch(updateToken(null));
      } finally {
        setAuthInitialized(true);
      }
    };
    initAuth();
  }, [dispatch]);

  // 鉴权未完成时只渲染loading,不渲染任何路由内容
  if (!authInitialized) return <div>加载中...</div>;

  return (
    {/* 你的路由配置 */}
    <Routes>
      <Route path="/login" element={<登录页组件 />} />
      <Route path="/私有路径" element={
        <PrivateRoute>
          <私有页面组件 />
        </PrivateRoute>
      } />
    </Routes>
  )
}

方案2:PrivateRoute组件内处理

如果不想在根组件加逻辑,也可以直接在私有路由组件内统一处理鉴权校验:

import { Navigate } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { getCurrentSession } from './cognito工具文件路径';
import { updateToken } from './你的auth切片路径';

const PrivateRoute = ({ children }) => {
  const [checkingAuth, setCheckingAuth] = useState(true);
  const dispatch = useDispatch();
  const token = useSelector(state => state.auth.token);

  useEffect(() => {
    const checkValid = async () => {
      // redux无token时才调用Cognito接口校验本地存储的token有效性
      if (!token) {
        try {
          const session = await getCurrentSession();
          if (session) {
            const accessToken = session.getAccessToken().getJwtToken();
            dispatch(updateToken(accessToken));
          }
        } catch (err) {
          localStorage.removeItem("user");
        }
      }
      setCheckingAuth(false);
    };
    checkValid();
  }, [token, dispatch]);

  if (checkingAuth) return <div>鉴权中...</div>;

  return token ? children : <Navigate to="/login" replace />;
}

注意事项

  • 不要尝试用同步逻辑阻塞组件渲染,React生态下没有稳定可靠的同步阻塞方案,加loading状态是成本最低、兼容性最好的实现方式
  • 如果你的项目用了Redux Toolkit Query等工具,也可以把鉴权逻辑放在全局middleware中处理,效果和根组件初始化一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:24:01