React - Router explanation

Who could explain what is happening in PrivateRoute function ?
I’ll be very appreciate if you explain how it all works together

The PrivateRoute function is simply a component (stateless functional component) that returns a Route component with different things inside the render function depending on whether a user is currently authenticated or not.

Consider the following code:

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => <Component {...props} />}
);

… when you render this component (<PrivateRoute path="/protected" component={Protected} />), the first thing that happens is that the component prop is assigned to the Component identifier, and the rest using the rest parameters with the spread syntax.

If I’m not mistaken, the reason that the component prop is reassigned to the Component identifier is because the JSX <component> attempts to create a component DOM element (which doesn’t exist) instead of a React component—a capitalised identifier is required for creating a React component.

The function then returns a <Route> component, which has the ...rest rest parameters from earlier. Since the component prop has already been assigned to Component, the only thing that’s left is path, so the code is now equivalent to the following JSX:

<Route path="/proteted" render={props => <Component {...props} />

The render function of the route component allows route props to be passed down in case you need them, this is in the documentation and I assume you know already know what route props are so I won’t go into it.

So the code for PrivateRoute from earlier is kind of useless because, in this case, <PrivateRoute path="/protected" component={Protected} /> is effectively returning <Route path="/protected" component={Protected} />.

If the above is clear (hopefully so!) then the only difference in the code that you are trying to understand is the ternary operator inside the render function that checks whether or not someone is authenticated and returns either the protected component OR a <Redirect> component:

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

The sample code above (from the React-Router documentation) rewritten without the ternary operator is:

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={(props) =>
      const { isAuthenticated } = fakeAuth;

      if (isAuthenticated) {
        return <Component {...props} />;
      }
      else {
        return (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />  
        );
      }
    }}
  />
);

I hope that helps! :slight_smile:

1 Like