Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing props in protected route reactjs

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?

like image 843
A.S.J Avatar asked Mar 01 '18 08:03

A.S.J


3 Answers

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"/>
        )} />
);
like image 165
Dyo Avatar answered Nov 15 '22 16:11

Dyo


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>
  );
}
like image 43
robert Avatar answered Nov 15 '22 15:11

robert


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>
  );
}
like image 2
Gabriel Bleu Avatar answered Nov 15 '22 15:11

Gabriel Bleu