0

I'm trying to build a login form using react and node.js and the Redirect & Routing doesn't work for me.

I have set in the App.js the Routes, and called a component which validate's all the variables and needs to redirect to Admin page or User page. My problem is with the redirect. If im redirecting I'm reciving the "Maximum update depth exceeded" error, and if im routing im the page is blank.

//App.js:
 <BrowserRouter>
       <div className="App">
          <CheckLogin/> {/*Validation component */}
            <Route exact path="/" component={Login}/>
            <Route path="/admin" component={AdminHome}/>
            <Route path="/user" component={UserHome}/>
       </div>
      </BrowserRouter> 
//CheckLogin.js:
      state={
        UserDataFromDB:{},
      }


componentDidMount=()=>
    {
      if (this.state.UserDataFromDB.ans)
      {
          console.log('there is ans');
      }
      else
      {
      axios.get(`http://localhost:4000/CheckLogin`, { withCredentials: true }) 
            .then(response => {

                // this.setState({ Cookie: response.data.id });
                this.setState({ UserDataFromDB: response.data })
            })
            .catch(error => {

                console.log("error: ", error);
            })
        }
    }
RouteSomewhere()
    {
      if(this.state.UserDataFromDB.ans==0)
      {
        return  <Redirect to='/'/>
      }
        if (this.state.UserDataFromDB.role==1)
        {
      return<Redirect to="/admin"/>
         }
    if (this.state.UserDataFromDB.role==0)
    {
      return <Redirect to="/user"/>
    }
    }
render() {
 return (
        <div className="CheckLogin">
{this.RouteSomewhere()}
</div>
    );
  }
}

I expect that the page will Redirect into the other page.. now im reciving the "Maximum update depth exceeded" Error.

Thanks :)

  • So you're getting this error in routeSomewhere()? I don't understand why you are checking where to route to w/ the if-else statements. – McFloofenbork Jun 04 '19 at 19:59
  • Had simmilar issue recently. Maybe this will help? https://stackoverflow.com/questions/56418972/navigate-to-the-url-without-react-router-this-props-history-is-undefined-er – kubwosz Jun 04 '19 at 20:23
  • @kubwosz Hey, Thanks, but I think it won't help in this case... I need to understand how the Redirect works, as it causes the error. If im switching the Redirect to Route it does pass me to the wanted page, but it's blank – Elick Chitrit Jun 04 '19 at 20:53

3 Answers3

1

Short answer - check the route before redirect.

Long answer - this happends because your <CheckLogin/> component renders every time with your application. So on every time it runs {this.RouteSomewhere()} no matter wher it is. And because it not re-mounted every time, the internal state remains the same, which caused the next redirect, which caused next render and then next redirect....and you in loop.

So, what you should do - or add check if you on desired URL and if yes - stop doing redirects,

//CheckLogin.js:
  state={
    UserDataFromDB:{},
    isRedireted: false,
  }


componentDidUpdate() {
    const targetURL = this.getRedirectURL();
    if (window.location.pathname === targetURL && !this.state.isRedireted) {
        this.setState({
            isRedireted: true;
        })
    }
}

getRedirectURL(UserDataFromDB) {
    if (UserDataFromDB.ans==0) {
        return '/';
    } else if (UserDataFromDB.role==1) {
        return '/admin';
    }  else if (UserDataFromDB.role==0) {
        return '/user';
    }
    return null;
}
RouteSomewhere() {
    if (this.state.isRedireted) { // If we already there - do nothing
        return null;
    }

    return <Redirect to={this.getRedirectURL(this.state.UserDataFromDB)} />;
}

or redirect programaticaly (see Programmatically navigate using react router V4 for examples) in the axios.get callback.

componentDidMount=()=> {
    if (this.state.UserDataFromDB.ans) { // On mount you won't have anythig here, so this code is always skipped.
        console.log('there is ans');
    } else {
        axios.get(`http://localhost:4000/CheckLogin`, { withCredentials: true }) 
            .then(response => {
                cosnt redirectURL = this.getRedirectURL(response.data);
                if (redirectURL) {
                    history.push(redirectURL);
                }
            })
            .catch(error => {
                console.log("error: ", error);
            })
        }
    }
Mykola Prymak
  • 397
  • 2
  • 5
0

I think you should not validate in App.js as your codes. If you want to validate users, you have to do it in components like AdminHome, UserHome, ... If you want to validate in one component, you need to have only one parent component to show other components. Good luck.

Diamond
  • 2,754
  • 1
  • 9
  • 31
  • Thanks for your answer. but I'm not quiet understand what do you mean... I do validate it on another component... Or am I just comfused? Can you please clerify? – Elick Chitrit Jun 04 '19 at 20:44
  • I recommend doing not to use `` unnecessarily. You can do all most things you want without using ``. :D – Diamond Jun 04 '19 at 21:00
0

if ans == 0 you're routesomewhere function gets called in the checklogin render function, which routes you back to '/' and refreshes the checklogin component, which calls the routesomewhere function in it's render function...you see where this is going.

Not routing back to '/' on ans == 0 would solve it for you. running routesomewhere on some sort of action instead of in every render cycle would solve it.