DEV Community

Christos Maris
Christos Maris

Posted on • Edited on

State Management with Vanilla JavaScript

TL;DR

| Check this Codepen out.


Intro

After reading this article on how to create a state management library using Vanilla JS I was intrigued to do something similar but in a more developer-friendly manner.

We basically want something that makes it easy for us to update the state, without having to invoke functions like setState and without having to trigger a UI refresh manually. This means that we should be able to do something like App.state.count++; and that should be enough for the UI to be refreshed.

For this reason, we will be using JS Proxies.
Basically, a Proxy is like a middleman between you (the developer) and the object you are trying to read or edit. It allows us to intercept and redefine fundamental operations for that object, which is a fancy way of saying that we know every time someone tries to edit or read a property from that object.


Code

Now in order for us to create a basic state management system, we need to create the following things:

  1. The App returns the UI that encapsulates the app state.
  2. The App State encapsulates
    • the actual state object
    • and the middleware proxy.

The App

| All we want from the app is to return a UI that basically displays the state.

const App = function _App() {
  return `
    <h1>Vanilla State Management</h1>
    <button onClick='App.state.count++;'>You pressed me ${App.state.count} ${App.state.count === 1 ? 'time' : 'times'}!</button>
  `;
};
Enter fullscreen mode Exit fullscreen mode

The App State

| The State Object in combination with the Middleware Proxy that updates the UI every time something in the state object is changed.

const handler = {
  set: function(obj, prop, value) {
    obj[prop] = value;
    document.getElementById('app').innerHTML = App();
  },
};

App.state = new Proxy({ count: 0 }, handler);
Enter fullscreen mode Exit fullscreen mode

Wrap Up

| This is what the complete thing looks like.

<body>
  <div id="app">loading...</div>
  <script>
    const App = function _App() {
      return `
        <h1>Vanilla State Management</h1>
        <button onClick='App.state.count++;'>You pressed me ${App.state.count} ${App.state.count === 1 ? 'time' : 'times'}!</button>
      `;
    };

    const handler = {
      set: function(obj, prop, value) {
        obj[prop] = value;
        document.getElementById('app').innerHTML = App();
      },
    };

    App.state = new Proxy({ count: 0 }, handler);

    // Initial Loading of the App
    document.getElementById('app').innerHTML = App();
  </script>
</body>
Enter fullscreen mode Exit fullscreen mode

Top comments (0)