7

I'm using protected routes in my reactjs application and I would like to know how to pass props in a protected route or if there is a more elegant way to solve my problem.

The reason why I feel the need to pass a props in a protected route, is that the logout button lies within the protected components and I need to communicate to the parent component, which contains all the routes, that the user is trying to log out.

Here is the relevant code:

Parent component:

render() {
    const PrivateRoute = ({ component: Component, ...rest }) => (
        <Route {...rest} render={(props) => (
            isAuthenticated === true
            ? <Component {...props} /*I tried inserting handleLogout={this.handleLogout} here */ />
            : <Redirect to="/Login"/>
        )} />
    )

return (
<HashRouter basename={BASE_URL}>
    <div className="stories-module">
    <PrivateRoute
        exact
        path={'/login'}
        component={Login}
      />
    <PrivateRoute
        exact
        path={'/Main/'}
        component={Main}
    />
</HashRouter>
)};

Unfortunately, I don't know how else I could resolve this issue.

Is it considered bad practice to pass props in a route component? If so, how else can I handle this and if not, how do I pass the prop properly?

1
  • What you are trying should work but you may move your PrivateRoute declaration outside of the class scope. Commented Mar 1, 2018 at 9:29

3 Answers 3

13

Declare your PrivateRoute outside of the class :

const PrivateRoute = ({ component: Component, handleLogout, isAuthenticated, ...rest }) => (
        <Route {...rest} render={(props) => (
            isAuthenticated === true
            ? <Component {...props} handleLogout={handleLogout} />
            : <Redirect to="/Login"/>
        )} />
);

Then pass handleLogout to your PrivateRoute props :

render() {
    return (
        <HashRouter basename={BASE_URL}>
            <div className="stories-module">
                <Route
                     exact
                     path={'/login'}
                     component={Login}
                />
                <PrivateRoute
                     exact
                     path={'/Main/'}
                     component={Main}
                     handleLogout={this.handleLogout}
                     isAuthenticated={isAuthenticated}
                />
            </div>
        </HashRouter>
    )
};

You may want to declare you PrivateRoute like below in order to pass any prop to the component by spreading all props :

const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => (
        <Route {...rest} render={(props) => (
            isAuthenticated === true
            ? <Component {...props} {...rest} />
            : <Redirect to="/Login"/>
        )} />
);
Sign up to request clarification or add additional context in comments.

4 Comments

@A.S.J You're welcome, just one question, is your login route intended to be private ?
No, the login should be public. Why are you asking?
Because it's declared as a PrivateRoute in the code so you should'nt have access to it on logout.
Oh yeah that's not my actual code, that was a silly mistake. In my app it's public, not sure what I was thinking
4

Here is a more general solution to pass as many props to the component as you want:

render() {
  const PrivateRoute = ({ component: Component, data, ...rest }) => (
    <Route {...rest} render={(props) => (
        isAuthenticated === true
        ? <Component {...props} {...data} />
        : <Redirect to="/Login"/>
    )} />
  );

  return (
    <HashRouter basename={BASE_URL}>
      <PrivateRoute
        exact
        path={'/login'}
        component={Login}
        data={{
            handleLogout=this.handleLogout,
            ...
            someProp=this.prop
        }}
      />
      <PrivateRoute
        exact
        path={'/Main/'}
        component={Main}
        data={{
            handleLogout=this.handleLogout,
            ...
            someProp=this.prop
        }}
      />
    </HashRouter>
  );
}

1 Comment

The above failed for me until I changed handleLogout=this.handleLogout to handleLogout:this.handleLogout
2

Add an extra prop to your PrivateRoute HOC

render() {
  const PrivateRoute = ({ component: Component, handleLogout, ...rest }) => (
    <Route {...rest} render={(props) => (
        isAuthenticated === true
        ? <Component handleLogout={handleLogout} {...props} />
        : <Redirect to="/Login"/>
    )} />
  );

  return (
    <HashRouter basename={BASE_URL}>
      <PrivateRoute
        exact
        path={'/login'}
        component={Login}
        handleLogout={this.handleLogout}
      />
      <PrivateRoute
        exact
        path={'/Main/'}
        component={Main}
        handleLogout={this.handleLogout}
      />
    </HashRouter>
  );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.