I can't seem to get my React private route to work

Viewed 41

I feel like it's something simple but I'd appreciate some insight as I am still a beginner with React. I have a private route setup and an authToken from the state of App.js that I send through props. The private route is supposed to go to /HomePage if authToken is true, but every time I press the login button with valid credentials, it redirects me to /login.

App.js

import ReactDOM from 'react-dom';
import HomeNavBar from './HomeNavBar.js'
import Login from './Login.js'
import Register from './Register.js'
import '../index.css';
import Routes from '../routes.js';
import axios from 'axios';
import qs from 'qs';
import HomePage from './HomePage.js';
import {Redirect} from 'react-router-dom';

class App extends React.Component {

    constructor(props) {
        super(props);
        this.state = { apiResponse: "",
          email: "",
          password: "",
          authToken: false
        };
        this.setEmail = this.setEmail.bind(this);
        this.setPass = this.setPass.bind(this);
        this.handleRegister = this.handleRegister.bind(this);
        this.handleLogin = this.handleLogin.bind(this);
        axios.defaults.withCredentials = true;
    }


    async handleLogin(){

        if(this.state.email == "" || this.state.password == "") {
            alert("Please complete form.");
        }
        else{

            const{email, password} = this.state;

            const user = {
                email,
                password,
            };

            var userId = 0;
            await axios
                .post('http://localhost:9000/api/getUserLogin', user)
                .then(function (response){
                    console.log(response);
                    userId = response.data.userId;
                    //alert(userId);
                })
                .catch(err => {
                    console.log(err.response);
                });
            if(userId != 0){
                this.state.validUser = true;
            }

            if(this.state.validUser){
                this.state.authToken = true;
            }
            else{
                this.state.authToken = false;
            }
        }
    }

    render() {
        return (
            <div className="HomeNavBar">
                <Routes  password = {this.state.password} email = {this.state.email} setPass = {this.setPass} setEmail = {this.setEmail} handleRegister = {this.handleRegister} handleLogin = {this.handleLogin} authToken = {this.state.authToken}/>
                <p className="App-intro">{this.state.apiResponse}</p>      
            </div>   
        );
    }

Routes.js

import { Switch, Route, Router, withRouter } from 'react-router-dom';

/**
 * Import all page components here
 */
import App from './components/App';
import Login from './components/Login.js';
import Register from './components/Register.js';
import HomePage from './components/HomePage.js';
import PrivateRoute from './privateRoutes.js';

/**
 * All routes go here.
 * Don't forget to import the components above after adding new route.
 */
 export default function Routes(props) {
    return (
        <div>
        <Switch>
          <Route path='/Login'>
        <Login setPass = {props.setPass} setEmail = {props.setEmail} handleLogin = {props.handleLogin} />
      </Route>

          <Route path='/Register'>
        <Register setPass = {props.setPass} setEmail = {props.setEmail} handleRegister = {props.handleRegister} />
      </Route>

      <PrivateRoute authToken={props.authToken} path='/HomePage' component={HomePage} />

      <Route path='/'> 
        <Login setPass = {props.setPass} setEmail = {props.setEmail} handleLogin = {props.handleLogin}  />
      </Route> 

        </Switch>
        </div>
    );
}

privateRoutes.js

import { Route, Redirect } from 'react-router-dom';

const PrivateRoute = ({component: Node, authToken, ...rest }) => (
  <Route
    {...rest}
    render={props =>
      authToken ? (
        <Node {...props} />
        ) : (
        <Redirect
          to={{
            pathname: "/Login",
            state: {from: props.location}
          }}
        />
      )
    }
  />
);

export default PrivateRoute;
1 Answers

So I thought that altering the state of the component would cause the render. For example, I thought "this.state.authToken = false;" would re-render the components which led me to be confused on why my auth token wasn't being updated properly, or anything really. I then learned I needed to use "this.setState" to assign values. All of my state values are working because of that, and my private route now works.

Related