Your app should be using query/search params
Tags: react, webdev, javascript
Published: 2019-11-24 19:46:21

If you're a long term web dev who is thinking "Of course I should be using query params! I've been using them since before you were born.", feel free to read something else.

Like many other of my contemporaries, there are concepts we can go years without learning. The use of query parameters or search parameters in single page apps was one such thing for me, and hopefully some of you as well! 

Query parameters / search parameters are a part of the official url standard. Take this url for example:
https://www.youtube.com/watch?v=y8EQFhj8ca4, the bit after the question mark `v=y8EQFhj8ca4` is a query parameter. If you go to that page and investigate in the console.
```javascript
let params = new URLSearchParams(document.location.search.substring(1))
params.get('v') 
```

You'll get access to the id of that video, `y8EQFhj8ca4`. I haven't checked but I'd bet serious money that id is used to fetch data in the client-side javascript without the necessity of defining a route for every video. This is one valuable use case for query parameters.

The core realization to be made is this: <b>_Query params make your urls shareable_</b>.

Don't see what I mean? Take an instance like a paginated table, each page of the table corresponds to a unique fetch or set of fetches for that page's data. Each fetch takes a "limit" argument, the number of rows we are looking to fetch, and an "offset" argument, the index at which we want to start fetching the rows. Assume they are always ordered the same way for the purpose of this discussion.

In that past I have made the mistake of managing the current page number and rows per page via React's `useState` hook, and building that into a larger `usePagination` hook. A clear limitation of this approach would be that whenever we took a url while from viewing some page that was not on the default state, that state was not saved anywhere and could not be reconstructed.

By using query params, we can react to the url to set determine current `limit` state and `offset` values to be sent to our fetch. When changing a page, we can use a react-router 5.1 and some url parsing to get what we need.


```javascript
// import react, react-router...
const { push } = useHistory();
const { pathname, search }  = useLocation();
const params = new URLSearchParams(search.substring(1))
// convert to numbers
const limit =  +params.get('limit')
const pageNumber = +params.get('pageNumber')
// fetch using offset on your own
const offset = limit * pageNumber
// an event handler you might pass to your table
const handlePageChange = (event, newPage) => {
    push({ pathname, search: `?limit=${limit}&pageNumber=${newPage}`})
```

By using routes and our router to our advantage we this approach means that when viewing page number 10 of some table, an end user can take this link, share it with a coworker, and they should get the same view. (Assuming the data hasn't changed in that time), either way, it creates a much better experience to the end user. 

Functions and utilities used while learning this stuff
--
URLSearchParams
react-router, specifically:
useHistory from react-router
useLocation from react-router
the `use-query-params` package on npm
mui-datatables

--


I'm trying not to punish myself by creating the perfect blog, so if anything is unclear or if you have anything you want to add, feel free to comment. I'm sure there is stuff I haven't brought up that is relevant!