Skip to content

Instantly share code, notes, and snippets.

@gragland gragland/use-router.jsx
Last active Mar 5, 2020

What would you like to do?
React Hook recipe from
import { useParams, useLocation, useHistory, useRouteMatch } from 'react-router-dom';
import queryString from 'query-string';
// Usage
function MyComponent(){
// Get the router object
const router = useRouter();
// Get value from query string (?postId=123) or route param (/:postId)
// Get current pathname
// Navigate with with router.push()
return (
<button onClick={(e) => router.push('/about')}>About</button>
// Hook
export function useRouter() {
const params = useParams();
const location = useLocation();
const history = useHistory();
const match = useRouteMatch();
// Return our custom router object
// Memoize so that a new object is only returned if something changes
return useMemo(() => {
return {
// For convenience add push(), replace(), pathname at top level
push: history.push,
replace: history.replace,
pathname: location.pathname,
// Merge params and parsed query string into single "query" object
// so that they can be used interchangeably.
// Example: /:topic?sort=popular -> { topic: "react", sort: "popular" }
query: {
...queryString.parse(, // Convert string to object
// Include match, location, history objects so we have
// access to extra React Router functionality if needed.
}, [params, match, location, history]);

This comment has been minimized.

Copy link

HaNdTriX commented Oct 22, 2019

Please don't do this. The react-router team splitted these hooks by propose.

Some of these hooks never change others may change quite often.
If a component just needs a react-router hook that doesn't change it will be rerendered by the useRouter hook above, even though it doesn't need to.

I've already seen many people implementing the useRouter without knowing the price of it.


This comment has been minimized.

Copy link
Owner Author

gragland commented Nov 6, 2019

Please don't do this. The react-router team splitted these hooks by propose.

I mentioned in the post description that there are performance concerns and that it makes sense that react-router would split hooks. That said, is this really that bad? Next.js has a single useRouter hook for the same data and I assume that was a tradeoff they felt made sense.

I generally prefer the better DX and would only want to drop down into lower-level hooks for specific cases where an extra re-render could lead to performance problems (which is pretty rare for me, even with complex deeply nested apps). Maybe I'm missing something though. Don't want to lead people astray if there are serious issues with this method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.