React Router: Redirect with Higher-Order Component

 by Robin Wieruch
 - Edit this Post

When using React Router in React, one can use the Navigate component to navigate a user away from a page in case of a certain condition. For example, the following example does not if there is no data, but redirects a user to the home page instead:

import { Navigate } from 'react-router-dom';
const List = ({ data }) => {
if (!data.length) {
return <Navigate replace to='/home' />;
}
return (
<ul>
{data.map((item) => {
return <li key={item}>{item}</li>;
})}
</ul>
);
};
export default List;

In this case the redirect is well placed. However, if there is much logic happening before of the conditional, e.g. by using (because they cannot be after a conditional rendering except with this ), then the logic has to execute even though there may be a redirect.

import { Navigate } from 'react-router-dom';
const List = ({ data }) => {
// lots of hooks here
// which is bad, because they execute
// even though there may be a redirect
// and all the hooks logic may not be used after all
if (!data.length) {
return <Navigate replace to='/home' />;
}
return (
<ul>
{data.map((item) => {
return <li key={item}>{item}</li>;
})}
</ul>
);
};
export default List;

Therefore, you can use a (HOC) for the redirect, because when wrapping the component into a HOC, the logic of the HOC would occur before the hooks from the wrapped component:

import { withRedirectIfBlank } from './withRedirect'
const List = ({ data }) => {
// lots of hooks here
return (
<ul>
{data.map((item) => {
return <li key={item}>{item}</li>;
})}
</ul>
);
};
export default withRedirectIfBlank({
redirectCondition: (props) => !props.data.length,
redirectTo: '/home',
})(List);

The HOC implementation could look like the following then:

import { Navigate } from 'react-router-dom';
const withRedirectIfBlank = (config) => (Component) => (props) => {
const { redirectCondition, redirectTo } = config;
if (redirectCondition(props)) {
return <Navigate replace to={redirectTo} />;
}
return <Component {...props} />;
};
export { withRedirectIfBlank };

Higher-Order Components are still useful these days, even though many React developers take them as legacy, because they are from a time when where used. Especially when they are used to render conditional JSX. However, if not using any conditional JSX, is often a better design choice in modern React.

Keep reading about 

So far, you've used broad authorization rules that check user authentication, where the dedicated authorization higher-order component redirects them to the login page if the user is not authenticated…

A React Router tutorial which teaches you how to use Nested Routes with React Router 7 . The code for this React Router v7 tutorial can be found over here . Nested Routes are a powerful feature…

The Road to React

Learn React by building real world applications. No setup configuration. No tooling. Plain React in 200+ pages of learning material. Learn React like 50.000+ readers.

Get it on Amazon.