react-router Redirect vs history.push

React RouterReact Router-V4React Router-ReduxReact Router-Dom

React Router Problem Overview


I was reading react-router-redux examples and I confused, what is the difference beetween:

import { Redirect } from 'react-router-dom'

...

<Redirect to='/login' /> 

and

import { push } from 'react-router-redux'

...

push('/login')

React Router Solutions


Solution 1 - React Router

Redirect

Rendering a <Redirect> will navigate to a new location. The new location will override the current location in the history stack, like server-side redirects (HTTP 3xx) do.

whereas History

push function Pushes a new entry onto the history stack

Solution 2 - React Router

The <Redirect> component will, by default, replace the current location with a new location in the history stack, basically working as a server-side redirect.

But it can also be used with the property push and in this case it will push a new entry into the history stack, working the same way as history.push.

In fact the <Redirect> component uses the history push and replace methods behinds the scene. It is just a more React way of navigating.

So basically you have two ways of navigating:

  1. Use the history.push and history.replace in a component (usually wrapped with the withRouter HOC, so that you can have access to the location object without having to pass it from parent to child.

  2. Use the <Redirect> component with or without the push property, depending

Solution 3 - React Router

I noticed a difference between the two in my use case with Redux and Typescript.

Here's a simplified version of it:

export const LandingPage = () => {
  const { history } = useHistory();
	const { viewer } = useSelector(state => state.viewer);

	// Redirect method returns another component that handles the redirect
	// without mounting any of the route components
	if (!viewer?.token) {
		return <Redirect to="/signin" />;
	}

	// History.push method mounts the route component and runs 'onload' functions
	// Which can still throw an error if there's no viewer 
	// if (!viewer?.token) {
	//	history.push('/signin');
	//    // return history.push('/signin');  // throws Typescript error
	// }

	return (
		<Switch>
			<Route path="/dashboard" component={Dashboard}/>
			<Route path="/profile" component={Profile}/>
			<Route path="/" component={Home}/>
		</Switch>
	);
};

When using history.push() method, the JSX in your return statement can still mount and run, whereas returning Redirect can block the rest of your code.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontandavView Question on Stackoverflow
Solution 1 - React RouterRevansiddhView Answer on Stackoverflow
Solution 2 - React RouterMarcos AbreuView Answer on Stackoverflow
Solution 3 - React RoutertoomusaView Answer on Stackoverflow