我已经创建了一个Reaction应用程序,该应用程序具有登录、入职流程和仪表板.入职流程包括两个页面,即创建组织和邀请成员.登录是由Aws Amplify处理的,它也有谷歌的登录.显示这些页面时要判断的条件如下.

Conditions:

  1. 任何用户都可以看到登录页面.
  2. 如果登录用户是新用户,他们必须通过入职流程
  3. 组织创建和邀请成员路由都只能由登录用户访问.
  4. 只有已登录且已完成入职流程的用户才能查看仪表板页面.这是组织创建和邀请成员.如果登录的用户尚未完成入职流程,则应导航到组织创建页面.(自注册流程判断将通过API调用进行).如果用户没有登录,他们应该导航到登录页面.

为了达到这些条件,我创建了一个这样的代码.我遇到的问题是,用户登录并导航到组织创建页面后,里面的内容没有显示,我不确定为什么.

但没有登录的人会被导航到登录,里面的内容也会显示出来.

发生这种情况的具体原因是什么?我是否需要单独的包装来判断入网是否完成?我在同一个地方处理这两个问题.

App.tsx

import { Amplify } from 'aws-amplify';
import { BrowserRouter } from 'react-router-dom';
import AppRoutes from './routes/Routes';


function App() {
  return (
    <>
      <BrowserRouter>
        <AppRoutes />
      </BrowserRouter>
    </>
  );
}

export default App;

路由.多伦多证券交易所

import { Navigate, Route, Routes } from 'react-router-dom';
import ProtectedRoutes from './ProtectedRoutes';

export default function AppRoutes() {
  return (
    <>
      <Routes>
        
        <Route path="login" element={<SignIn />} />
        <Route
          path="create-org"
          element={<ProtectedRoutes component={<CreateOrg  />} />}
        />
  <Route
          path="invite-members"
          element={<ProtectedRoutes component={<InviteMembers  />} />}
        />
  <Route
          path="dashboard"
          element={<ProtectedRoutes component={<Dashboard />} />}
        />
    <Route path="/" element={<Navigate to="/dashboard" />} />

      </Routes>
    </>
  );
}

ProtectedRoutes.tsx

import React, { useEffect, useState } from 'react';
import { Navigate , Outlet} from 'react-router-dom';

interface ProtectedRouteProps {
  component: React.ReactNode;
}

const ProtectedRoutes: React.FC<ProtectedRouteProps> = ({component}) => {
  const [isLoading, setIsLoading] = useState(true);
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [hasCompletedSteps, setHasCompletedSteps] = useState(false);

  useEffect(() => {
    const checkUser = async () => {
      try {
        const authUser = await getUserAccessToken();
        setIsAuthenticated(authUser ? true : false);
        if (authUser ) {
          const onboardingComplete = await otherService.get('/onboarding');
       

          if (check for the onboarding process) {
            setHasCompletedSteps(false);
          } else {

            setHasCompletedSteps(true);
          }
          setIsLoading(false);
        } else {
          setIsLoading(false);
        }
      } catch (error) {
        setIsLoading(false);
        setIsAuthenticated(false);
      }
    };

    checkUser ();
  }, []);

  if (isLoading) {

    return <p>Loading...</p>;
  }


  if (isAuthenticated && !hasCompletedSteps) {    
    return <Navigate to='/create-org' replace />;
  }

  return <>{component}</>;
};

export default ProtectedRoutes;

推荐答案

我认为你让你的ProtectedRoutes组件做的太多了,特别是因为你有一条路由需要在多个条件下保护.我的建议是将判断身份验证和判断登录的责任分成两个独立的组件.

示例:

import React, { useEffect, useState } from 'react';
import { Navigate , Outlet, useLocation } from 'react-router-dom';

const ProtectedRoutes = () => {
  const { pathname } = useLocation();

  const [isLoading, setIsLoading] = useState(true);
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    const checkUser = async () => {
      setIsLoading(true);

      try {
        const authUser = await getUserAccessToken();
        setIsAuthenticated(!!authUser);
      } catch (error) {
        setIsAuthenticated(false);
      } finally {
        setIsLoading(false);
      }
    };

    checkUser();
  }, [pathname]);

  if (isLoading) {
    return <p>Loading...</p>;
  }

  return isAuthenticated
    ? <Outlet />
    : <Navigate to='/login' replace />;
};

export default ProtectedRoutes;
import React, { useEffect, useState } from 'react';
import { Navigate , Outlet, useLocation } from 'react-router-dom';

const OnboardedRoutes = () => {
  const { pathname } = useLocation();

  const [isLoading, setIsLoading] = useState(true);
  const [hasCompletedSteps, setHasCompletedSteps] = useState(false);

  useEffect(() => {
    const checkOnboarded = async () => {
      setIsLoading(true);

      try {
        const authUser = await getUserAccessToken();

        if (authUser) {
          const onboardingComplete = await otherService.get('/onboarding');

          setHasCompletedSteps(!!check for the onboarding process);
        }
      } catch (error) {
        setHasCompletedSteps(false);
      } finally {
        setIsLoading(false);
      }
    };

    checkOnboarded();
  }, [pathname]);

  if (isLoading) {
    return <p>Loading...</p>;
  }

  return hasCompletedSteps
    ? <Outlet />
    : <Navigate to='/create-org' replace />;
};

export default OnboardedRoutes;
import { Navigate, Route, Routes } from 'react-router-dom';
import ProtectedRoutes from './ProtectedRoutes';
import OnboardedRoutes from './OnboardedRoutes';

export default function AppRoutes() {
  return (
    <Routes>
      <Route path="login" element={<SignIn />} />

      <Route element={<ProtectedRoutes />}>
        <Route path="create-org" element={<CreateOrg />} />
        <Route path="invite-members" element={<InviteMembers />} />

        <Route element={<OnboardedRoutes />}>
          <Route path="dashboard" element={<Dashboard />} />
        </Route>

      <Route path="/" element={<Navigate to="/dashboard" />} />
    </Routes>
  );
}

Typescript相关问答推荐

Angular -使用Phone Directive将值粘贴到控件以格式化值时验证器不工作

您可以创建一个类型来表示打字员吗

TypScript ' NoInfer '类型未按预期工作

TypeScript实用程序类型—至少需要一个属性的接口,某些指定属性除外

如果请求是流,如何等待所有响应块(Axios)

如何避免推断空数组

在另一个类型的函数中,编译器不会推断模板文字类型

无法将从服务器接收的JSON对象转换为所需的类型,因此可以分析数据

避免混淆两种不同的ID类型

我怎样才能正确地输入这个函数,使它在没有提供正确的参数时出错

17个Angular 的延迟观察.如何在模板中转义@符号?

Typescript,如何在通过属性存在过滤后重新分配类型?

打字错误TS2305:模块常量没有导出的成员

如何使用useSearchParams保持状态

如何在TypeScript中描述和实现包含特定属性的函数?

在对象数组中设置值

为什么类方法参数可以比接口参数窄

如何将 MUI 主题对象的自定义属性与情感样式组件中的自定义props 一起使用?

基于泛型类型的条件类型,具有条目属性判断

类型为 `(callback: (...args: T) => void, params: T)` 的函数的泛型