4. Basic example
Now that we know how to use urlBuilder
and useQueryParams
let’s see it in action.
Here’s a basic example containing a Dashboard
component which uses
both query params and path parameters.
4.1 Dashboard
There are two options; a hook called useQueryParams
and a Higher Order
component called withQueryParams
. The preferred solution is useQueryParams
because it avoids a Higher order Component.
4.1.1 via useQueryParams
// Dashboard.tsx
import React from 'react';
import { useParams, useLocation } from 'react-router';
import { Url, useQueryParams, urlBuilder } from '@42.nl/react-url';
type DashboardPathParams = {
id: string /* All path params are strings */;
}
type DashboardQueryParams = {
page: number;
query: string;
}
export function defaultDashboardQueryParams(): DashboardQueryParams {
return {
page: 1,
query: '',
};
}
/*
By extending RouteComponentProps we get the standard props that
react-router adds when the component in a route.
*/
export default function Dashboard() {
/* The `id` is a string which can be found on the params. */
const { id } = useParams<DashboardPathParams>();
const location = useLocation();
const queryParams = useQueryParams({
location,
defaultQueryParams: defaultDashboardQueryParams(),
debugName: 'Dashboard',
});
const { page, query } = queryParams;
return (
<div>
<h1>
Hello {id} You are on page {page} with query {query}.
</h1>
</div>
);
}
export const DASHBOARD_URL = '/dashboard/:id';
export function toDashboard(pathParams: DashboardPathParams, queryParams?: Partial<DashboardQueryParams>): Url {
return urlBuilder({
url: DASHBOARD_URL,
pathParams,
queryParams,
defaultQueryParams: defaultDashboardQueryParams(),
});
}
4.1.2 via withQueryParams
We recommend using
useQueryParams
whenever possible. This method only works withRoute
as defined fromreact-router < 5.1.0
.
// Dashboard.tsx
import React, { Component } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { Url, withQueryParams, urlBuilder } from '@42.nl/react-url';
import { toDashboard } from './links';
interface DashboardPathParams {
id: string /* All path params are strings */;
}
interface DashboardQueryParams {
page: number;
query: string;
}
/*
The default query params are used when no query params are provided
or when one query param is missing.
*/
export function defaultDashboardQueryParams(): DashboardQueryParams {
return {
page: 1,
query: '',
};
}
/*
By extending RouteComponentProps we get the standard props that
react-router adds when the component in a route.
*/
interface Props extends RouteComponentProps<DashboardPathParams> {
queryParams: DashboardQueryParams /* Add the query params to it */;
}
export class Dashboard extends Component<Props> {
/*
You now have access to the query params via the props.
The `id` is a string which can be found on the match.
*/
render() {
const { queryParams, match } = this.props;
const { page, query } = queryParams;
const id = match.params.id;
return (
<div>
<h1>
Hello {id} You are on page {page} with query {query}.
</h1>
</div>
);
}
}
/*
This is the important part, the Dashboard is wrapped in a
Higher order Component which provides the `queryParams` prop for use in the Dashboard.
*/
export default withQueryParams(Dashboard, defaultDashboardQueryParams());
export const DASHBOARD_URL = '/dashboard/:id';
export function toDashboard(pathParams: DashboardPathParams, queryParams?: Partial<DashboardQueryParams>): Url {
return urlBuilder({
url: DASHBOARD_URL,
pathParams,
queryParams,
defaultQueryParams: defaultDashboardQueryParams(),
});
}
4.2 Routes
Next you can add the Dashboard
to the router like this:
// Routes.tsx
import React from 'react';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
import Dashboard, { DASHBOARD_URL, toDashboard } from './Dashboard';
export default function Routes() {
return (
<BrowserRouter>
<div>
<Link to={toDashboard({ id: 1 })}>Dashboard</Link>
<Switch>
<Route exact path={DASHBOARD_URL}>
<Dashboard />
</Route>
</Switch>
</div>
</BrowserRouter>
);
}
Now that we have seen a basic example it is time to show more complex use cases.