Dispatching using query parameters in react-router
react-router is the de-facto standard for routing in react.js-based applications. It’s easy to use, has multiple backends and can be used with react native, too. We found one feature lacking, however: you cannot easily route based on a query parameter. For example, this code is easily read and understood¹:
function About() {
return <h2>About</h2>;
}function Users() {
return <h2>Users</h2>;
}function AppRouter() {
return (
<Router>
<Route path="/about" component={About} />
<Route path="/users" component={Users} />
</Router>
);
}
This way, you can openhttp://localhost:3000/about
and get the “About” headline. However, what if your URL looks like http://localhost:3000/index.html?page=about
? You’re out of luck, because the path
parameter doesn’t know how to parse query strings.
Luckily, the solution is pretty simple. You wrap your routes in a route that transforms the location
property of the render props. Our AppRouter
function then looks like this:
function AppRouter() {
return (
<Router>
<Route render={(routeProps) => (
<Switch location={transformLocation(routeProps.location)}>
<Route path="/about" component={About} />
<Route path="/users" component={Users} />
</Switch>)
/>
</Router>
);
}
Note that we’re using <Switch>
here to have no (accidentally) overlapping routes.
The transformLocation
function might look like this:
function transformLocation(inputLocation: Location): Location {
const queryStringParsed = parseQuery(inputLocation.search);
if (queryStringParsed.page === undefined) {
return inputLocation;
}
return {
...inputLocation,
pathname: "/" + queryStringParsed.page,
};
}
Here, we are using thequery-string
package to parse the query string and extract the page
parameter and transform it into a path parameter.
This solution “works for us”, and allows other query string transformations. If you know of a better, more “native” solution to this problem, please let us know.
¹ We are omitting imports and exports here for brevity.