React Router has a useSearchParams
hook to help us read or update the query string of a route that’s active, but it doesn’t allow us to transition to another route and set query params at the same time. So, you may be asking “how can I navigate to a URL whilst setting query string search params?” - here’s how!
✨ Written for React Router v6, check out my brand new React Router v6 course to fully master it.
React Router v6 ships with a useNavigate
hook, which returns us a function that we can call to navigate around our apps with. These actions are typically done after some data processing or an event callback, a simple example looks like so:
const Users = () => {
const navigate = useNavigate();
const goToPosts = () => navigate('/posts');
return (
<div>
Users
<button onClick={goToPosts}>Go to Posts</button>
</div>
);
};
We can also pass in some options instead, which then would allow us to set a string value to set as search params:
const Users = () => {
const navigate = useNavigate();
const goToPosts = () =>
navigate({
pathname: '/posts',
search: '?sort=date&order=newest',
});
return (
<div>
Users
<button onClick={goToPosts}>Go to Posts</button>
</div>
);
};
But this doesn’t allow us to specify any search params that we might have as an object. Nobody likes strings anymore. We like (and trust) data structures.
So, what next? Nested in the basement of the react-router-dom
package, you’ll find a function called createSearchParams
. Ooh-la-la, what could it do?
Free eBook
Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.
- Observables and Async Pipe
- Identity Checking and Performance
- Web Components <ng-template> syntax
- <ng-container> and Observable Composition
- Advanced Rendering Patterns
- Setters and Getters for Styles and Class Bindings
Create search params of course! It transforms an object into a string for you to then set via the useNavigate
hook in React Router.
Here I’ve created a params
object with some values to demonstrate:
const Users = () => {
const navigate = useNavigate();
const params = { sort: 'date', order: 'newest' };
const goToPosts = () =>
navigate({
pathname: '/posts',
search: `?${createSearchParams(params)}`,
});
return (
<div>
Users
<button onClick={goToPosts}>Go to Posts</button>
</div>
);
};
Yep, that’s it. There are lots of great features like this in React Router, and this is a nice little wrapper around the native URLSearchParams
object. This means that it can support multiple formats, such as “entries”, essentially a multidimensional array. Perhaps your data is in that format already or you’re using an existing URLSearchParams
object:
const Users = () => {
const navigate = useNavigate();
const params = [
['sort', 'date'],
['order', 'newest'],
];
const goToPosts = () =>
navigate({
pathname: '/posts',
search: `?${createSearchParams(params)}`,
});
return (
<div>
Users
<button onClick={goToPosts}>Go to Posts</button>
</div>
);
};
🕵️♀️ Just remember to include the
?
at the beginning of the string, because the whole string is appended to the URL!
Here’s a working example in StackBlitz of what we’ve covered here to see it in action:
Hopefully this gives you some nice ideas for your next React Router project, and don’t forget to include the ?
in your query string!
Bonus: Create a Custom Hook
You could also wrap this logic inside of your own custom React hook:
const useNavigateSearch = () => {
const navigate = useNavigate();
return (pathname, params) =>
navigate({ pathname, search: `?${createSearchParams(params)}` });
};
const Users = () => {
const navigateSearch = useNavigateSearch();
const goToPosts = () =>
navigateSearch('/posts', { sort: 'date', order: 'newest' });
return (
<div>
<p>Users</p>
<button onClick={goToPosts}>Go to Posts</button>
</div>
);
};
And there you have it! A custom React hook that accepts a url and object or entries array. Of course, a working demo:
💯 If you are serious about your React skills, your next step is to take a look at my React courses where you’ll learn React, React Router, Styling and CSS practices, advanced concepts and APIs as well as server-side rendering and much more.
Happy navigating!