3

I have a React Route that looks something like this...where it conditionally renders a Component based on the value of a URL parameter:

<Route path="/blog/:postId" render={(props) = {
    const postId = props.match.params.postId; // extract post from url
    return (
        post
        ? <Post {...props} postId={postId} />
        : <div>Post does not exist</div>
    );
}

I want only authenticated users to be able to access this Route, which means I'd be turning it into a PrivateRoute like this (from the docs):

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

And then I'd use the Private Route like this...

<PrivateRoute path="/blog/:postId" component={Post} />

But how can I examine the URL parameters within the PrivateRoute and conditionally render the Post component depending on the URL parameter?

dd_123
  • 93
  • 1
  • 7

1 Answers1

1

You can write it like this:

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route
    {...rest}
    render={props => {
      const postId = props.match.params.postId;
      return fakeAuth.isAuthenticated ? (
        postId ?
          <Component {...props} />
          : <div>Post does not exist</div>
      ) : (
        <Redirect
          to={{
            pathname: "/login",
            state: { from: props.location }
          }}
        />
      )
    }}
  />
);

But it will be not a good idea because if in future you want one more condition then PrivateRoute will become more complex. I will suggest to put all the kind of check inside Post component itself, like this:

render(){
   if(!this.props.match.params.id)
     return <div>Post does not exist</div>
   else (.....)
}

Or if you don't want to change the Post component then create a wrapper component and put this logic inside that, like this:

<PrivateRoute path="/blog/:postId" component={PostWrapper} />

const PostWrapper = props => {
   if(props.match.params.id)
      return <Post {...props} />
   return <div>Post does not exist</div>
}
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142