0

I found online how to create a costumed private route, However, I'm getting an error

"Cannot read property 'state' of undefined" on line 12 I'm kinda new to react and I'm having trouble understanding props vs this.

Router.js

import React, { Component } from 'react';
import { Route, BrowserRouter, Redirect } from "react-router-dom";

import Login from './Authentication/Login';
import  Register  from './Authentication/Register';
import PageRouter from './page/PageRouter';
import Profile from './page/Profile';
import Rankings from './page/Rankings';
import Shop from './page/Shop';

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


class Router extends Component{
    constructor(props){
        super(props);
        this.state = {
            login: false,
        }
    }

    render(){
        return(
            <div>
                <BrowserRouter>
                <Route exact path="/" component={ Register }></Route>
                    <Route path='/register' component={ Register }/>
                    <Route path="/login" component={ Login } />
                    <PrivateRoute path='/home' component={ PageRouter } />
                    <Route path ='/profile' component={ Profile } />
                    <Route path = '/rankings' component={ Rankings } />
                    <Route path = '/shop' component={ Shop }/>
                </BrowserRouter>          
            </div>
        );
    }
}

export default Router;

Any information would help. Thanks!

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • Does this answer your question? [Why "this" is undefined inside a fat arrow function definition?](https://stackoverflow.com/questions/38589227/why-this-is-undefined-inside-a-fat-arrow-function-definition) – Dan O Mar 03 '20 at 14:39
  • 1
    there are many, many, many Stack Overflow questions regarding react, component state, fat-arrow functions, and `this` being undefined. which of them did you research and try to use to solve your problem and why specifically did they not work for you? – Dan O Mar 03 '20 at 14:40
  • 1
    To use this.setState() you need to use lcass based component: `class PrivateRoute extends React.Component` – DennyHiu Mar 03 '20 at 14:42
  • I think that you mix the concept of `this.state` with `state` properties that is a parameter from `Redirect` component of 'react-router-dom' – DennyHiu Mar 03 '20 at 14:54
  • Does this answer your question? [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Emile Bergeron Mar 03 '20 at 15:30

2 Answers2

0

This isn't a React issue. The key you're missing here is understanding JavaScript context. Right now PrivateRoute's lexical scope is the global or window object (or if in strict mode undefined). You currently have no state on that object. If you want a way to utilize your Router class' state, then I would suggest you pass in some prop to PrivateRoute via Router.

So if you wanted to access the login property on state try something like:

<PrivateRoute path='/home' component={ PageRouter } isLoggedIn={this.state.login} />

then your PrivateRoute would have access to a prop called isLoggedIn which you could use in your ternary.

ehutchllew
  • 940
  • 8
  • 14
  • The only problem with that is that it wont run render() again even though my state as change and therefore will be stuck at state:false all the time –  Mar 03 '20 at 15:02
-1

"Cannot read property 'state' of undefined" on line 12 I'm kinda new to react and I'm having trouble understanding props vs this.

  1. Props is (in simple terms) a collection of attibutes that your component needs, eg: <MyComponent name="xxx" address="yyy"/> where name and address can be accessed by this.props.name or this.props.address respectively.
  2. Keyword this is a different concept altogether. this referring to the component itself. It means, you can access its (component) state, props, or methods that is defined inside the component class

I don't know if this is related to your issue or not, but I noticed that your sample code is coming from a tutorial (https://tylermcginnis.com/react-router-protected-routes-authentication/).

Below is my implementation of PrivateRoute:

const PrivateRoute = ({ component: Component, ...rest }: {component: any}) => (
    <Route {...rest} render={(props) => (
        fakeAuth.isAuthenticated === true
            ? <Component {...props} />
            : <Redirect to={{
                pathname: '/login',
                state: { from: props.location }
            }} />
    )} />
)

PrivateRoute.propTypes = {
    component: PropTypes.any,
    location: PropTypes.string,
    path: PropTypes.string
};

The state properties is not this.state. It is a parameter from Redirectof react-router-dom

DennyHiu
  • 4,861
  • 8
  • 48
  • 80