Title: How to Detect the Previous Path in React Router
When using React Router to navigate between pages in your React app, you may have a need to determine the previous path or page you came from. However, the router object in React Router doesn’t provide a built-in property like “previous path” or history to directly access this information. In this blog post, we will explore several approaches to detect the previous path in React Router.
Detecting the Previous Path Using State
One approach is to pass down the previous path as state using the <Link>
component. By including the pathname
and state
properties in the <Link>
component, you can access the previous path in the next component through this.props.location.state
.
<Link to={{ pathname: '/nextpath', state: { prevPath: location.pathname } }}>Example Link</Link>
In the next component, you can access the previous path like this:
const prevPath = this.props.location.state.prevPath;
Passing the Current Page as Props
Alternatively, instead of trying to detect the previous path, you can approach the problem from a different angle. Pass the current page as props to the component or link you’re navigating to. In the previous page or component, add a state of the current page using history.push
or by clicking the link. Then, you can access the previous page using history.location.state.from
.
history.push('/nextpath', { from: 'current page' });
Using Component Lifecycle Method
If you prefer using the componentWillReceiveProps
lifecycle method, you can save the previous path in the state. By comparing the nextProps location with the current props location, you can detect a change and set the previous path accordingly.
componentWillReceiveProps(nextProps) {
if (nextProps.location !== this.props.location) {
this.setState({ prevPath: this.props.location });
}
}
Integrating with React Router Redux
If you are using react-router-redux
, you can create a reducer that hooks into events dispatched by react-router-redux
. This way, you can maintain a stack of location changes and access the previous paths through the state.
export default function routerLocations(state = [], action) {
switch (action.type) {
case "@@router/LOCATION_CHANGE":
return [...state, action.payload];
default:
return state;
}
}
Using useHistory Hook (React Router v5)
If you’re using React Router v5 and functional components, you can leverage the useHistory
hook to go back to the previous path. By calling goBack()
from useHistory
, you can easily navigate to the previous path.
import { useHistory } from "react-router-dom";
function MyComponent() {
const history = useHistory();
const goToPreviousPath = () => {
history.goBack();
};
return (
<div>
<button onClick={goToPreviousPath}>Go Back</button>
</div>
);
}
Using Custom Hook for Browser Back Stack
If you want to maintain a back stack of locations in the browser, you can create a custom hook using history.listen
. This hook stores the back stack as state and allows you to navigate back through the previously visited paths.
import { useEffect, useState } from 'react';
import { useHistory } from 'react-router';
const useBrowserBackStack = () => {
const history = useHistory();
const [backStack, setBackStack] = useState([]);
useEffect(() => {
history.listen((location, action) => {
setBackStack(backStack => {
switch (action) {
case 'POP':
return backStack.slice(0, backStack.length - 1);
case 'PUSH':
return [...backStack, location];
case 'REPLACE':
return [...backStack.slice(0, backStack.length - 1), location];
}
});
});
}, [setBackStack, history]);
return backStack;
};
// Usage
const backStack = useBrowserBackStack();
React Router v6 (Navigate, Link, useNavigate)
For those using React Router v6, there are new options available. You can use the <Navigate>
component, <Link>
component, or the useNavigate
hook to pass the previous URL to the next component. In the redirecting component, you can set the state through the to
or navigate
functions. Then, in the redirected component, you can access the previous path through the state.
<Navigate to="/nextpath" state={{ from: location }} />
const navigate = useNavigate();
navigate("/nextpath", { state: { from: location } });
In the redirected component, you can access the previous path like this:
const location = useLocation();
const from = location.state?.from?.pathname;
By implementing these different approaches, you can easily detect the previous path in React Router and take appropriate actions based on the user’s navigation history within your application.