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 render a list 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 React Hooks (because they cannot be after a conditional rendering except with this little trick), 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 allif (!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 higher-order component (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 herereturn (<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 React Class Components where used. Especially when they are used to render conditional JSX. However, if not using any conditional JSX, using a Hook instead of a HOC is often a better design choice in modern React.