Read other articles

Lifting up the state

~4 min read  ⦁  Updated on Jan 21 2024

Summary: native state management


In this article
  1. Introduction
  2. Enter the browser’s URL: the primordial store
  3. URLSearchParams (parameters)
  4. The typical state management on the client
  5. Combining state hooks and URLSearchParams
  6. Conclusion

One of the first thing most web developers working on an application do when the need to handle state arises is to reach out to the JavaScript framework’s state management “hook”. React.js has useState(), Vue.js has ref(), Solid.js has createSignal() (these frameworks do provide other hooks to manage the state).

Introduction

It is common to see, in tutorials, courses and tweets, developers showcasing simple (and sometimes complex) apps using one of these frameworks. What they also tend to do is to always use the state hook of the framework to manage state (thus providing reactivity to the application).

There is nothing wrong with that. But what if there was another way? What if, e.g., useState() was not needed in all components? The new (as in 2023) React.js docs have a detailed article on how to reduce the amount of controlled state to prevent unnecessary re-renders. Even though that might, in part, have to deal with the nature of React.js, similar strategies are also recommended in other JavaScript frameworks.

Still on this matter, a youtube video from Sam Selikoff made me aware of a primitive store, compatible with all JavaScript frameworks, that can simplify the removal of unnecessary controlled state in our applications.

Enter the browser’s URL: the primordial store

URLs are the backbone of the web; everything that is done in this medium is through it. An URL has several parts (protocol/scheme, domain, port, path to a file, parameters and anchor. Let us focus on the parameters.

URLSearchParams (parameters)

These are also called query/search params and are usually part of most web pages that allow the user to sort, filter, order, choose viewing layout, etc.

In a normal HTML form element the default method is GET and when we submit the form, each field in it is added to the page URL as a search/query param. Here’s an example.

<form>
  <label for="userName">
    Full name
  </label>
  <input id="userName" name="name" type="text" required />
  <label for="country">
    Country
  </label>
  <select id="country" name="nationality" required >
    <-- options -->
  </select>
  <button>
    Search
  </button>
</form>

Upon the submission of the form above, the browser’s default behaviour would be to navigate to the current URL + the fields of the form as search parameters; if the form was in the current page, https://www.miltondavid.com/blog/lifting-up-the-state, after the submission the new URL would be https://www.miltondavid.com/blog/lifting-up-the-state?name=A%20name%20here&nationality=A%20nationality%20here.

How we would deal with the form submission and/or use these search parameters would depend on many factors (rendering strategy (SSR, CSR, ISR, SSG, etc), goal and routing choice). The focus of this article lies on the client, so let’s see how we can take advantage of the search parameters to manage our application state.

The typical state management on the client

In a common todo app (using React) that allows you to add, edit and remove todos as well as sort, filter and display them as list or grid, the code would be similar to the one you can find in this repository . It uses useState() to manage the list of todos (add, delete, edit), and to set the filter for the list of todos.

Combining state hooks and URLSearchParams

The alternative to the previous approach consists in:

You can see this in detail in the same repository, just on a different branch . */}

Conclusion

Combining the insert your framework here state hook and the URLSearchParams can greatly simplify the state management in your applications, re-introduce the shareability of URLs (SPAs are bad at this) and, probably, improve the performance of applications that relies on several setStateActions on each re(re)nder. Tanner Linsley takes this even further by advocating, when applicable, the storing of a JSON stringified state in the URL, here’s a youtube video about it.

I hope you can find interesting ways to apply this approach in your current/next application. */


Did you find a typo, or would like to contribute to the article? Here's the Github Link for this article.

Share this article: Twitter | Linkedin