React with TypeScript - 授权和组件可见性取决于用户声明

React with TypeScript - Authorization and component visibility depending on user claims

我正在开发一个 React 应用程序。

我正在尝试创建登录和注册功能。

我有一个 Authorized.tsx 组件,看起来像这样

export const Authorized = (props: authorizedProps) => {
  const [isAuthorized, setIsAuthorized] = useState(true);
  const { claims } = useContext(AuthContext);

  useEffect(() => {
    if (props.role) {
      const index = claims.findIndex(
        claim => claim.name === 'role' && claim.value === props.role)
      setIsAuthorized(index > -1);
    } else {
        setIsAuthorized(claims.length > 0);
    }
  }, [claims, props.role]);

  return (
    <>
        {isAuthorized ? props.authorized : props.notAuthorized}
    </>
    );
};

interface authorizedProps {
  authorized: ReactElement;
  notAuthorized?: ReactElement;
  role?: string;
}

此组件根据用户是否获得授权隐藏和显示不同类型的组件。

我使用此组件只为未登录的用户显示 Login.tsx 组件。我不希望任何未登录的人能够访问该网站。

在我的 Index.tsx 中,我正在使用这样的 Authorized.tsx 组件

const Index = () => {
  const [claims, setClaims] = useState<claim[]>([
    // { name: "email", value: "test@hotmail.com" },
  ]);

  return (
    <div>
      <BrowserRouter>
        <AuthContext.Provider value={{ claims, update: setClaims }}>
          <Authorized authorized={<App />} notAuthorized={<Login />} />
        </AuthContext.Provider>
      </BrowserRouter>
    </div>
  );
};

所有授权用户都可以访问该站点,其他所有人都需要登录。

但是,当我尝试将 Register.tsx 组件作为导航 link.

添加到 Login.tsx 组件时,我遇到了问题

我希望能够在 RegisterLogin

之间导航

这就是 Login.tsx 组件的样子

export const Login = () => {

  return (
    <>
      <h3>Log in</h3>
      <DisplayErrors errors={errors} />
      <AuthForm
        model={{ email: "", password: "" }}
        onSubmit={async (values) => await login(values)}
        BtnText="Log in" />
          <Switch>
            <Route path="/register">
              <Register />
            </Route>
            <Link to='/register'>Register</Link>
          </Switch>
    </>
  );
};

但是当我按下 'Register' link 时实际发生的是 Register 组件被添加到 Login 组件下方

在按下之前 'Register' link

按下后 'Register' link

我了解到它与 Index.tsx 中的 Authorized.tsx 组件有关。 我告诉它只在未授权时显示登录组件。

但我不知道如何修复它所以我将能够在 LoginRegister

之间导航

我将不胜感激所有能得到的帮助!

谢谢

在当前的实现中,您正在渲染一个 Login 组件,然后该组件还会渲染一个 Register 组件的路由。 Login 始终保持安装和渲染状态。根据您的描述,您想在各自的路线上渲染 LoginRegister

将这两个组件抽象为管理路由匹配和渲染的父组件。

例子

const Unauthenticated = () => (
  <Switch>
    <Route path="/register" component={Register} />
    <Route component={Login} />
  </Switch>
);

...

export const Login = () => {
  ...

  return (
    <>
      <h3>Log in</h3>
      <DisplayErrors errors={errors} />
      <AuthForm
        model={{ email: "", password: "" }}
        onSubmit={login}
        BtnText="Log in"
      />
      <Link to='/register'>Register</Link>
    </>
  );
};

...

const Index = () => {
  const [claims, setClaims] = useState<claim[]>([
    // { name: "email", value: "test@hotmail.com" },
  ]);

  return (
    <div>
      <BrowserRouter>
        <AuthContext.Provider value={{ claims, update: setClaims }}>
          <Authorized
            authorized={<App />}
            notAuthorized={<Unauthenticated />}
          />
        </AuthContext.Provider>
      </BrowserRouter>
    </div>
  );
};