Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is wrong with my custom authentication react-router route?

Unfortunately I fail to create a custom route with react-router version 4. I'm trying to construct a route which renders a component, if the user is authenticated or redirect the user to the login component in the other case.

I've been using this documentation page to get started.

const ProtectedRoute = ({component, ...rest}) => (
    <Route {...rest} render={props => false
        ? <Component {...props} />
        : <Redirect to={{pathname: '/login', state: {from: props.location}}}/>}
    />
);

I'm using this ProtectedRoute like this:

<ProtectedRoute exact path='/' component={testComponent}/>

When I run this, I get the following runtime error:

Uncaught ReferenceError: __rest is not defined
    at ProtectedRoute (index.tsx:19)
    at ReactCompositeComponent.js:305
    at measureLifeCyclePerf (ReactCompositeComponent.js:75)
    at ReactCompositeComponentWrapper._constructComponentWithoutOwner (ReactCompositeComponent.js:304)
    at ReactCompositeComponentWrapper._constructComponent (ReactCompositeComponent.js:279)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:187)
    at Object.mountComponent (ReactReconciler.js:45)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:236)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:703)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:522)

Here some more information about the stack I'm using:

  • react 15.6.1
  • react-router-dom 4.2.2
  • typescript 2.5.2

Why is rest not defined? What is wrong with my custom route?

Thank you in advance!

Update (minimal example)

A minimal example of the problem can be found here. To run the example follow these steps:

  • Install dependencies with yarn install
  • Run the dev server with yarn dev
  • Go to http://localhost:8080
like image 749
Robin Avatar asked Sep 03 '17 20:09

Robin


2 Answers

Okay, I know what's going on. In your tsconfig.json you declared this rule "noEmitHelpers": true which tells typescript compiler to not include any helpers functions like __rest in your output. That's why you have runtime error with __rest is not defined. Changing it to false should solve your problem.

like image 97
niba Avatar answered Oct 17 '22 04:10

niba


I'm not a Typescript expert and haven't dived into TS yet, but it's definitely the issue related to your attempt to use ...rest operator. I guess ts doesn't like spread operator within object destructuring and consequently the following structure (although it's going to work fine in ES6):

ProtectedRoute = ({component: Component, isAuthenticated, ...rest}) => {

If you rewrite your component with explicit usage of path prop it gets back to work well.

const ProtectedRoute = ({component: Component, isAuthenticated, path}) => {
    return <Route
        path={path}
        render={props => isAuthenticated
            ? <Component {...props} />
            : <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
    />
}; 

But the fact that your code doesn't work seems strange to me, since it's mentioned that starting from 2.1 version typescript supports spread/rest within object destructuring: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#object-spread-and-rest

like image 43
Artyom Pranovich Avatar answered Oct 17 '22 06:10

Artyom Pranovich