In react-router-dom v6 the Route components no longer have route props (history, location, and match), and the current solution is to use the React hooks "versions" of these to use within the components being rendered. React hooks can't be used in class components though. To access the match params with a class component you must either convert to a function component, or roll your own custom withRouter Higher Order Component to inject the "route props" like the withRouter HOC from react-router-dom v5.x did. I won't cover converting a class component to function component. Here's an example custom withRouter HOC:
import {
useParams
} from "react-router";
///
let {
slug
} = useParams()
const withRouter = WrappedComponent => props => {
const params = useParams();
// etc... other react-router-dom v6 hooks
return (
<WrappedComponent
{...props}
params={params}
// etc...
/>
);
};
And decorate the component with the new HOC.
export default withRouter(Post);
import { ComponentType } from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom';
export interface WithRouterProps<T = ReturnType<typeof useParams>> {
history: {
back: () => void;
goBack: () => void;
location: ReturnType<typeof useLocation>;
push: (url: string, state?: any) => void;
}
location: ReturnType<typeof useLocation>;
match: {
params: T;
};
navigate: ReturnType<typeof useNavigate>;
}
export const withRouter = <P extends object>(Component: ComponentType<P>) => {
return (props: Omit<P, keyof WithRouterProps>) => {
const location = useLocation();
const match = { params: useParams() };
const navigate = useNavigate();
const history = {
back: () => navigate(-1),
goBack: () => navigate(-1),
location,
push: (url: string, state?: any) => navigate(url, { state }),
replace: (url: string, state?: any) => navigate(url, {
replace: true,
state
})
};
return (
<Component
history={history}
location={location}
match={match}
navigate={navigate}
{...props as P}
/>
);
};
};
import { Component } from 'react';
import { withRouter, WithRouterProps } from './withRouter';
interface Params {
id: string;
}
type Props = WithRouterProps<Params>;
class MyClass extends Component<Props> {
render() {
const { match } = this.props;
console.log(match.params.id); // with autocomplete
return <div>MyClass</div>;
}
}
export default withRouter(MyClass);
Finally, to access the value of the URL parameter from inside of the component that is rendered by React Router, you can use React Router's useParams Hook. Using React Router, when you want to create a Route that uses a URL parameter, you do so by including a : in front of the value you pass to Route's path prop. Notice that the path has a : in front of it. That's how you tell React Router that this portion of the URL is the "placeholder". Instead of matching literally for twitter.com/handle, it's matching for the specific pattern.
function getProfile(handle) { // `handle` is a placeholder // for when `getProfile` is invoked}
getProfile("tylermcginnis");
getProfile("cassidoo");
<Route path=":handle" element={<Profile />} />
import * as React from 'react'
import {
useParams
} from 'react-router-dom'
import {
getProfile
} from '../utils'
function Profile() {
const [user, setUser] = React.useState(null) const {
handle
} = useParams()
React.useEffect(() => {
getProfile(handle).then(setUser)
}, [handle])
return (...)
}
import * as React from "react";import { BrowserRouter as Router, Route, Routes, Link,} from "react-router-dom";
import { getPosts } from "./api";
function Home() { const posts = getPosts();
return ( <div> <h1>Posts</h1> <nav> <ul> {posts.map(({ id, title }) => ( <li key={id}> <Link to={`blog/${id}`}>{title}</Link> </li> ))} </ul> </nav> </div> );}
...
<Route path="blog/:id" element={<Post />} />
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: How to programmatically navigate with React Router v6 and the new useNavigate hook. React Router provides the <NavLink> element for us to declaratively navigate around our applications, it renders an <a href=""> for us ... Create search params of course! It transforms an object into a string for you to then set via the useNavigate hook in React Router.
const Users = () => {
const navigate = useNavigate();
const goToPosts = () => navigate('/posts');
return (
<div>
Users
<button onClick={goToPosts}>Go to Posts</button>
</div>
);
};
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>
);
};
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>
);
};
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>
);
};
Again, in order to get access to the URL Parameter with React Router v5, you use the useParams Hook. There are a variety of approaches that can be taken to solve the same problem Add Query Parameter To Url React Router V6. The remaining options will be discussed further down. To pass in query parameters, we just add them to the Link s to props as usual. For example, we can write the following: We first defined the useQuery Hook to get the query parameters of the URL via the URLSearchParams constructor. We get the useLocation() s search property.
We will use programming in this lesson to attempt to solve the Add Query Parameter To Url React Router V6 puzzle. This is demonstrated by the following code.
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>
);
};
history.push({
pathname: '/dresses',
search: '?color=blue'
})
or
history.push('/dresses?color=blue')
UtilitiescreateRoutesFromChildren createRoutesFromElements createSearchParams defer 🆕generatePath isRouteErrorResponse 🆕Location matchPath matchRoutes renderMatches resolvePath The useParams hook returns an object of key/value pairs of the dynamic params from the current URL that were matched by the <Route path>. Child routes inherit all params from their parent routes. ComponentsAwait 🆕Form 🆕Link Link (RN) NavLink Navigate Outlet Route Routes ScrollRestoration 🆕 RouteRoute 🆕action 🆕errorElement 🆕loader 🆕shouldRevalidate 🆕
declare function useParams< K extends string=string>(): Readonly<Params<K>>;
import * as React from 'react';
import { Routes, Route, useParams } from 'react-router-dom';
function ProfilePage() {
// Get the userId param from the URL.
let { userId } = useParams();
// ...
}
function App() {
return (
<Routes>
<Route path="users">
<Route path=":userId" element={<ProfilePage />} />
<Route path="me" element={...} />
</Route>
</Routes>
);
}
The best way to get URL parameters in React is to use the library “React Router”. Thanks to a set of functions, it helps you manage your application’s routes. But, if you have a simple application without routing, you can use the built-in URLSearchParams interface to fetch the query parameters. If you have a more complex application in React with many pages, you’re probably using React Router to manage your routes. This library is the most popular solution and has many features to manage your website URLs. In the rendering part of our application, we display the two React URL params, type, and name, thanks to the get() function from the URLSearchParams object.
import React from "react"
export default function App() {
const queryParameters = new URLSearchParams(window.location.search)
const type = queryParameters.get("type")
const name = queryParameters.get("name")
return (
<div>
<p>Type: {type}</p>
<p>Name: {name}</p>
</div>
)
}
import React from "react"
import {
Routes,
Route,
useSearchParams,
BrowserRouter
} from "react-router-dom"
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
</Routes>
</BrowserRouter>
)
}
function Home() {
const [queryParameters] = useSearchParams()
return (
<div>
<p>Type: {queryParameters.get("type")}</p>
<p>Name: {queryParameters.get("name")}</p>
</div>
)
}
import React from "react"
import {
BrowserRouter as Router,
Switch,
Route,
useLocation
} from "react-router-dom"
export default function App() {
return (
<Router>
<Switch>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
)
}
function Home() {
const location = useLocation()
const queryParameters = new URLSearchParams(location.search)
return (
<div>
<p>Type: {queryParameters.get("type")}</p>
<p>Name: {queryParameters.get("name")}</p>
</div>
)
}