Notes on client-side Application & Website state

For neophytes

These notes explore basic concepts around state for websites and web applications loaded into web clients (e.g. web browsers) and briefly discusses component/locale state v.s. stores and state managers.

1 : Basic overview of client-side application & website state

Overview of the meaning of state in the context of websites and web applications loaded into a web client (e.g. a web browser).

In short, state is the word assigned to the current form of a thing (aka a snapshot) assuming that the thing can change or morph into something different. If a thing doesn't change, it can't have state and is typically considered stateless. If text on a web page already loaded into a web browser never changes, it is stateless. Similarly, if a user interface never changes it is a stateless UI. However, if a thing like a webpage or web application, after first loading it, has a thing about it that changes then it has state.

Specifically, in the context of webpages and web applications that run in a web browser client-side state (aka local state) is the data or variables that affects the content and form of a webpage or web application, in any way, during the lifetime of running it in a web browser. Let's unpack this a bit.

Consider that the first webpages created had no HTML forms and no hidden content, just viewable images and text. The web page was basically a static and stateless thing. You enter a url to a static stateless web page and what you get is a thing that does not change after loading (except for editions). This is not unlike a written page in a book. You buy a physical book, you open it, and the content before you won't change. Open the book the next day and most likely the book and the content in the book is changeless. The book, by design, is in a single state and won't ever change.

Now what if a book could change its state, based on data, in a real-time'ish manner? This is basically the revolutionary aspect of the internet and web pages as the world wide web evolved. You get to interact with data that can change almost in real-time, by user engagement.

Keep In Mind:

  1. Originally the world wide web was just a web of static/stateless documents for viewing (versioned, but pretty much thought of as book that could be updated and shared quickly). It did not originate as a platform for delivering interactive user interfaces that managed state, especially state inputted by users. History just unfolded this way because the WWW platform became ubiquitous.

Now, contrast a completely static stateless website like we just discussed to the web application you might use to do online banking today. You open this application in a web browser and immediately the application wants data from you to login. It's asking for you to change the state of the application from not logged in, to logged in. The second the username or password input field goes from empty to containing one typed character you have change the UI state of the HTML input used to collect your login credentials. Once you login into a banking application with your credentials the entire state of the UI changes from a sign-in/login view to a logged in view.

Generally speaking you should think of state, or maybe more specifically application state, as any type of data that one has to keep track of during a period of time a user is using a website or web application (aka a session). Some of this state you have to manually take care of. Some of it you get for free, like the fact that you can type characters into an HTML input and the state of the input changes in real-time and you have little to do with fact (i.e. the shadow-dom takes care of it for you).

To summaries, If you deliver a webpage with a single line of text to a user, the webpage is pretty much state-less and static even today. Much like a physical book. However, if you sent a user a banking application over the internet, then that application will have states that have to be managed over time (e.g. logged in status, the users location in the application, what the account balance is, which UI is currently being shown and what UI parts are hidden and what UI parts are shown by default etc..).

Keep In Mind:

  1. In the beginning state management for websites and web applications was mostly a backend affair. Today however, most web applications are either one-time-loaded single page application (SPA) or some hybrid version of page reloads and AJAX requests. Either way, as soon web pages and web applications get reduced to some degree of a thick/smart web client the runtime will have to have a mechanism to deal with state as it is being used/changed by the user (as opposed to a dumb client, that offloads state management to the backend, and just requests stuff and does nothing but display that stuff i.e. web 1.0).

2 : State in relation to time and storage

Thinking about state in an application based on where it is stored and for how long.

2.1 : Non-lasting state (aka ephemeral state)

If you enter a few characters into an HTML input on a web page you have change the state of the input. The input was empty and then you changed it by adding text characters to the input. The state of the input changed. Even the mere focusing of the input changes the state of the inputs UI from unfocused to focused. If an input is unfocused and the characters are gone, then this is typically consider non-lasting state. The state changes by design, are meant to be lost after a period of time.

2.2 : Short-lasting state (aka session state)

Short-lasting state typically has a pre-conceived end, but does not really fall into the category of non-lasting state. Short-lasting state is the type of state that the developer of a system purposely keeps track of for a short period of time with a known expiration. For example, you logged into your banking website site and we are going to keep you logged for X number of minutes or until you close the browser session, then the state of being logged in for that session is lost, but it is designed to be held for a known period of time (e.g. sessionStorage).

2.3 : Long lasting state (aka permanently stored state or persisted state)

Contrasted to short lasting state long lasting state is typically data that is stored indefinitely until it is specifically deleted at a unknown time (i.e. anytime). If you enter data into a website or web application and that data is stored in some manner until you specifically (directly or indirectly) remove that data this is typically consider long lasting state. Long lasting state can be as simple as the last view/location of the UI a user was using or a set of data like drafts from a checking account. Basically, if you have logic, to save state for an indefinite amount of time, until that data is removed, it is likely long lasting state. Many think of long lasting state as back-end data but the client can also store long lasting data (i.e. indefinite cookies, localStorage etc...)

Keep In Mind:

  1. State is commonly trivialize for good reason into two buckets based on its relationship to time. State that is save (i.e. data) to the back-end and state that is temporary (i.e. the current value of a text input). This simplified delineation can be helpful at times.

3 : Types of State based on its nature.

This section catagories the most common types of state by the nature of the state itself.

Type of state:

  • Session state: State about the users current interaction with the website or application (e.g. are they logged). Typically session state can be short-lasting or long-lasting.
  • Entity (aka Domain or Data or Business Logic or Model state): A banking apps Entity state could be the account information or ledger for the banking account. Typically entity state is long lasting state. Think of Entity state as the data in your application (e.g. if it is a todo app the data of a todo application is a todo).
  • Communication state: State concerned with communication to non-local content. Is the user connected? Is the front-end talking to the back-end. Waiting on the Back-end. Typically entity state can be non-lasting, short-lasting, or long lasting state.
  • Location state: Where the user is in the website or application and how the url effects the state of things the user is doing at a specific location. Typically location state can be short-lasting or long-lasting.
  • UI state (aka view state): Where the user is in the website or application and how the url effects the state of things the user is doing at a specific location. Typically location state can be short-lasting or long-lasting.

4 : Organizing state in relation to scope (i.e. what/who needs this state)

A facet of state or way to organize it, is defining who needs access to it. Often, developers will divide state into Global state and Relative state. These catagories can be helpful when managing a lot of state.

4.1 : Global State (aka Accessible Everywhere State)

Global state needs to be accessible from every part of your application.

Global state is typically stored either in global state "Stores" external to UI component trees (e.g. React) or at the very top of a UI component tree/branch. Once an application requires a significant amount of global state, used by many different components at many different locations in the component tree, developers will often start to use a third party state manager like Redux or Mobx. Often this is done to avoid prop drilling and boilerplate create from the avoidance of prop drilling (i.e. The React context api).

4.2 : Relative State (aka local state or component state)

Relative state is called relative state because the state is not typically required to be accessible to the entire application and is likely relative or local to a part of the application but not all of it, all the time. Relative state is stored in the client as close as possible to the part(s) of the app that need it. That is why it is called relative, because it is relative to something specific. In a React application this could be the internal state of a component or state that is consumed from a close by ancestral component (aka a container component or a smart component).

Keep In Mind:

  1. In a React application when state reaches the top of the component tree, and one is practicing the notion of lifting state and lifting it only as high as needed, then one is conceding that the state is global because all components can now access the state (via prop drilling or context api). At this point, the nature of the state changes from relative state to global state.

The line between global state and relative state can be a very subjective practice. Does one keep all of their state in global store(s) or does use both global state stores (e.g. Redux or Mobx) and local component state? Which type of state is keep where?

5 : Third-party state managers (e.g. Flux, Redux, Mobx, Apollo Client, unstated etc.) v.s. component state (e.g. React component state)

What is the different between third-party state managers and local component state?

Fundamentally third-party state managers manage state outside of a tree of components inside of stores while local component state solutions manage state within the component tree relative to components. As an example, React has several mechanisms to manage state within a component (e.g., this.setState(), this.state, useState(), useReducer()) while Redux moves state and it's management to an object external from the components (Actions, Action Creators, Dispatcher, Reducers etc..).

Many developers use a combination of both because shoving global state or relative state through a single state solution can lead to maintenance nightmares (e.g. Redux boilerplate to support short-lasting UI state or layers of complex smart/container components at the top of the component tree).

6 : State Stores

Understanding how a state store relates to state itself.

State managers (e.g. Redux, Flux, or Mobx) typically store state in a state store. Not all state managers have the same understanding of a state store. But, basically, a state store is state wrapped with an interface (often just a pattern) for CRUD'ing state. A store is not state itself, a store houses the state. State managers update a store in very specific way so that any component/view using the state from a store always gets the most recent state. Some store managers think of state as a single store (e.g. Redux) that holds all state (i.e. a single state tree) while others think of state existing in several different stores (e.g. Flux).

7 : Derived or computed values from state

State should only be made up of the bare minimum things that change over time excluding things that can be derived or computed from minimal state seeds. Thus, anything that can be derived should be derived avoiding unnecessary state.

A derived value is a value that is a result or deducted from actual state. For example the first name (e.g. "Pat") and last name (e.g. "Jenson") of a user might be actual state, but the full name (e.g. "Pat Jenson") is a derivation of two pieces of state added together. The full name itself is not state it is a derivation of state.

Another example might the total number of completed todos in a todo application. This number is computed from the list of todos not stored as state itself.

Derived values are typically computed at runtime and are consider artifacts. Thus, derived/computed values are not typically consider state.