This is the final part of my exploration into state management and data structures.
In the previous section, we discussed the CustomEvent and EventTarget APIs, and how they can be used to build a Pub-Sub-like communication system between components.
In this part, I want to introduce another native method for transferring data — one of React's built-in features within its routing system (react-router) that can greatly simplify our work. But before that, it's important to understand that React Router works closely with the browser's History API. So whenever we use hooks like useNavigate or useLocation, we're actually interacting with native browser functionality under the hood.
Relationship between react-router and the History stack
Obviously react-router use winow.history
to manage navigation and state transitions.
The History Stack is part of the browser’s navigation system and it allows pages to:
- Push new entries (pushState)
- Replace the current entry (replaceState)
- Navigate backward and forward
So when we’re using method like navigate(“/some-url”), its internally doing:
Another navigation API available in the browser is window.location.href. We can reassign this property to navigate to a different URL. However, React Router and most SPA frameworks rely on the pushState and replaceState methods instead — and here’s why:
pushState:
- Doesn’t reload the page
- Adds a new entry to the browser’s history stack
- Allows passing state as a payload to the next page
- Ideal for SPAs
In contrast, window.location.href behaves like a traditional link. It performs a full page reload and is commonly used for navigating to external domains or outside the current application.
Now you can see how data transfer works in React Router.
As mentioned earlier, the pushState and replaceState methods allow us to pass data as a payload when navigating between pages in a single-page application.
Don’t worry about the second argument — it’s the title property, but most browsers ignore it. It was originally intended to set the page title shown in the browser history. (modern browsers rarely support or use it.)
Now let's use this inside React using useNavigate and useLocation. Imagine we want to send some data from the Home page to another page named Article
First we import useNavigate hook from react-router-dom and then call it with a string as url and an object with a state prop as payload.
We import useLocation from react-router-dom and use the state prop to get our data.
Note
As I mentioned, the useNavigate hook preserves data in the history stack. However, we need to remember that this state is not the same as React's internal state created with the useState hook. The navigation state, which we accessed earlier using useLocation, persists across page reloads so remember to remove it after you’re done with it.
We can do this using the useNavigate hook by passing location.pathname as the URL and an empty object as the state payload.
The navigation state is a simple and handy way to transfer state between two pages. One of its most important uses is tracking the user's last visited page within the current session.
In our project, I used this method to navigate the user from the Orders page—along with data related to a specific order—to the Shop page, where I used that order data to create a new basket for reordering.
You can try it for yourself and reorder something from the site — of course, you need to have a completed order first. :)
https://www.digikalajet.com/profile/orders
Next.js does not support navigation state, so it's not possible to pass a payload directly through router.push or router.replace. Instead, you can use alternatives like query parameters or persist the data in localStorage.
Next.js uses a file-based routing system and is designed with SSR. Browser-side state like a navigation payload would be lost unless passed via the URL or stored globally (like I said, in a context, Redux, or localStorage).
Top comments (0)