首页 > 解决方案 > React - 如何在钩子useEffect中使用重定向?

问题描述

我正在尝试将未登录到我的应用程序的用户重定向到登录页面,并且我的路由文件中的 useEffect 中有一些条件,但是当我输入其中一个时,重定向不起作用并且我想知道它是否与 react-router-dom 有关

Route.js 文件代码如下:

import React, { useEffect } from 'react'; // nao estava
import { PropTypes } from 'prop-types';
import { Route, Redirect, useHistory } from 'react-router-dom';

import AuthLayout from '../pages/_layouts/auth';
import DefaultLayout from '../pages/_layouts/default';

import { store } from '../store';

export default function RouteWrapper({
  component: Component,
  isPrivate,
  ...rest
}) {
  const { signed } = store.getState().auth;
  const { googleSigned } = store.getState().googleAuth;

  const history = useHistory();

  useEffect(() => {
    if (!signed && !googleSigned && isPrivate) {
      return <Redirect to="/" />;
    }

    if ((signed && !isPrivate) || (googleSigned && !isPrivate)) {

      return <Redirect to="/dashboard" />;

    }

    return <Redirect to="#" />;
  }, [googleSigned, signed]);

  const Layout =
    signed || googleSigned || window.location.pathname === '/dashboard'
      ? DefaultLayout
      : AuthLayout;

  return (
    <Route
      {...rest}
      render={(props) => (
        <Layout>
          <Component {...props} />
        </Layout>
      )}
    />
  );
}

RouteWrapper.propTypes = {
  isPrivate: PropTypes.bool,
  component: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
    .isRequired,
};

RouteWrapper.defaultProps = {
  isPrivate: false,
};

signed 和 googleSigned 是 reducer 中存在的状态,重点是 google 签名,因为尚未实现使用普通登录获得的签名,而 google 签名是在应用程序后端使用 oAuth 实现的

此时我的应用程序的流程如下,用户单击 google 上的登录按钮被重定向到 google 身份验证屏幕,如果用户在应用程序中注册,他将被重定向到仪表板页面,仪表板页面并发送一个动作检查用户是否登录到应用程序,目的是如果用户未登录(googleSigned = false),他将被重定向回登录页面

标签: reactjsredirectsigned

解决方案


您的实施存在一些问题。首先也是最重要的,回报useEffect并不像您希望的那样起作用。返回useEffect实际上用于清除副作用,例如滚动侦听器或您不想在组件卸载后保留的类似内容。您可以在此处阅读更多相关信息:https ://reactjs.org/docs/hooks-effect.html 。

相反,您要做的是以编程方式重定向用户,而不是返回重定向组件。react-router-dom你可以使用钩子useHistoryhttps://reactrouter.com/web/api/Hooks/usehistory)来做到这一点。因此,我们可以利用历史记录来代替在您的钩子中返回<Redirect />组件。useEffect

useEffect(() => {
    if (!signed && !googleSigned && isPrivate) {
      history.push("/");
    }

    if ((signed && !isPrivate) || (googleSigned && !isPrivate)) {
      history.push("/dashboard");
    }

    history.push("#");

}, [googleSigned, signed]);

像上面这样的东西应该更接近你想要实现的目标。


推荐阅读