0

I want to make a PrivateRoute in React with an async LoginCheck. I have tried this:

class App extends React.Component {
constructor(props) {
super(props);
this.state = {
loggedIn: false
}
}

componentDidMount() {
//ASYNC FUNCTION
setTimeout(() => {
this.setState({loggedIn: true});
}, 1000)
}

render() {

console.log("RENDERED", this.state.loggedIn);

const PrivateRoute = ({component: Component, ...rest}) => (
      <Route {...rest} render={(props) => (
         this.state.loggedIn === true
           ? <Component {...props} />
           : <Redirect to="/login" />
      )}/>
    )

return(
<Router>
<Switch>
<Route path="/" exact component={Home} />
<PrivateRoute path="/private" component={PrivatePage} />
</Switch>
</Router>
)
}
}

But that is not working. In the console it shows first "RENDERED false" and after a second "RENDERED true". So it is rendered with the right parameters but in the const PrivateRoute he is redirecting to the login page so loggedIn is false. Why? What can I do?

tom203
  • 77
  • 5
  • Does this answer your question? [Why is my React component is rendering twice?](https://stackoverflow.com/questions/48846289/why-is-my-react-component-is-rendering-twice) – Behelit Apr 25 '20 at 23:21

1 Answers1

0

You can create a function checkAuth() to seperate the validation as follow

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Redirect,
  Route,
} from "react-router-dom";
import Home from "./Home";
import PrivatePage from "./Private";



export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loggedIn: true
    }
  }

  componentDidMount() {
    //ASYNC FUNCTION
    setTimeout(() => {
      this.setState({ loggedIn: false });
    }, 1000)
  }

  render() {

    console.log("RENDERED", this.state.loggedIn);

    const checkAuth = () => {
      try {
        // To be replaced with your condition
        if (this.state.loggedIn === true) {
          return true;
        }

      } catch (e) {
        return false;
      }
      return false;
    }

    const PrivateRoute = ({ component: Component, ...rest }) => (
      <Route {...rest} render={props => (
        checkAuth() ? (
          <Component {...props} />
        ) : (
            <Redirect to={{ pathname: '/' }} />
          )
      )} />
    )

    return (
      <Router>
        <Switch>
          <Route path="/" exact component={Home} />
          <PrivateRoute path="/private" component={PrivatePage} />
        </Switch>
      </Router>
    )
  }
}

Visit the url "http://localhost/private" as loggedIn: true this route is authorized but after 0.2s the state of loggedIn will be update it false and the protected route will be redirected to the home page.

abnaceur
  • 252
  • 1
  • 2