Private routes with React-router with render method
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:

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 ofrender
orchildren
, below) the router usesReact.createElement
to create a new React element from the given component. That means if you provide an inline function to thecomponent
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 therender
or thechildren
prop.
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:

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.