简体   繁体   中英

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

the Route.js file code below:

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

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

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. 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. You can read more about that here: 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 ). So instead of returning the <Redirect /> component in your useEffect hook we can utilise history instead.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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