Private routes with React-router with render method

Navid Zarepak
3 min readOct 5, 2019

If you are a react developer, then you probably heard of private routes and probably have a way around the problem. The most common solution is to create a PrivateRoute component and use it whenever you need a private route. The code looks something like this:

Taken from @tomlarge

It works fine and you won't notice any problems until you need to use the render method instead of component.

The `render` method and the problem it tackles

Usually, we pass our component to the router as the component parameter like this:

But if you need to pass some data to your component or use a function to decide what your component should be, you are out of luck. As mentioned in react-router docs, you can’t pass functions to component. It works if you do so but you will run to performance issues, creating a new component instead of updating the old component being the main one.

When you use component (instead of render or children, below) the router uses React.createElement to create a new React element from the given component. That means if you provide an inline function to the component prop, you would create a new component every render. This results in the existing component unmounting and the new component mounting instead of just updating the existing component. When using an inline function for inline rendering, use the render or the children prop.

More: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Route.md#component

To solve the problem of using functions, they introduced render. Instead of passing a component, it receives a function and allows you to pass extra data or select a component based on different conditions:

More: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Route.md#render-func

What is the problem?

Okay, to the problem. So when you use render instead of component , the old version of our PrivateRoute will no longer work and you’ll be thrown an error like this:

But don’t worry, the fix is simple. The problem with our old code is that we are assuming that all of our routes use component and we are returning the component even if it’s undefined. To fix it, we need to check if the route has the component provided and if not, return the render method instead:

It’s a simple problem to fix but easy to forget since you write the PrivateRoute method at the beginning of your project and forget about it afterward.

--

--