简体   繁体   English

React - 如何在钩子 useEffect 内使用重定向?

[英]React - how to use redirect inside hook useEffect?

I'm trying to redirect a user who is not logged in to my application to the login page, and I have some conditions inside a useEffect that is inside my routes file, but when I enter one of them the redirect doesn't work and I want to know if it's something related to react-router-dom我正在尝试将未登录到我的应用程序的用户重定向到登录页面,并且我的路由文件中的 useEffect 中有一些条件,但是当我输入其中之一时,重定向不起作用并且我想知道它是否与 react-router-dom 有关

the Route.js file code below: 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 and googleSigned are states present in a reducer, the focus is google signed because the signed which is obtained using normal login is not implemented yet and the google signed is implemented using oAuth in the backend of the application signed 和 googleSigned 是 reducer 中存在的状态,焦点是 google 签名,因为使用正常登录获得的签名尚未实现,而 google 签名是在应用程序后端使用 oAuth 实现的

the flow of my application at this moment is as follows the user clicks the login button on google is redirected to the google authentication screen and if the user is registered in the application he is redirected to the dashboard page, the dashboard page and dispatch a action that checks if the user is logged in to the application, the purpose is that if the user is not logged in (googleSigned = false) he is redirected back to the login page此时我的应用程序的流程如下,用户单击 google 上的登录按钮被重定向到 google 身份验证屏幕,如果用户在应用程序中注册,他将被重定向到仪表板页面、仪表板页面并发送操作检查用户是否登录到应用程序,目的是如果用户未登录(googleSigned = false),他将被重定向回登录页面

There are some issues with your implementation.您的实施存在一些问题。 First and foremost, returns in useEffect don't work the way you seem to want them to work.首先, useEffect返回useEffect并不像您希望它们那样工作。 Returns in useEffect are actually used to cleanup side effects, for example scroll listeners or similar that you don't want to persist after your component unmounts. useEffect中的返回useEffect实际上用于清除副作用,例如滚动侦听器或您不想在组件卸载后保留的类似内容。 You can read more about that here: https://reactjs.org/docs/hooks-effect.html .您可以在此处阅读更多相关信息: https : //reactjs.org/docs/hooks-effect.html

What you want to do instead is to redirect the user programmatically instead of returning the redirect component.您想要做的是以编程方式重定向用户,而不是返回重定向组件。 With react-router-dom you can do that using the useHistory hook ( https://reactrouter.com/web/api/Hooks/usehistory ).使用react-router-dom您可以使用useHistory钩子 ( https://reactrouter.com/web/api/Hooks/usehistory ) 做到这一点。 So instead of returning the <Redirect /> component in your useEffect hook we can utilise history instead.因此,我们可以使用历史代替返回useEffect钩子中的<Redirect />组件。

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

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

    history.push("#");

}, [googleSigned, signed]);

Something like the above should work closer to what you are trying to achieve.像上面这样的东西应该更接近你想要实现的目标。

Maybe you want to implement Protected Route pattern?也许您想实现受保护的路由模式?

Protected Route 保护路线

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM