A common approach in React is to use boolean flags to keep track of state. For example, imagine we made a component that fetched an image. It could look like the following:
A disadvantage of this is it results in untended states. The intended amount of states for the component is 4; idle, fetching, success & error. The actual number of states produced from the above approach is 23 = 8. Changing the approach from boolean flags to named states can fix this:
Intended number of states = 4. Actual number of states = 4.
When state management requirements become complex, finite-state machines are the best approach to UI state management.
- ▪ Disable all user actions by default: Within each state, you have a centralized area where you define what events can occur, reducing edge cases.
- ▪ Seperation of concerns: Logic can be seperated from everything else. This allows logic to be reused when changing frameworks (such as moving from Angular to React), easier seperation of work between team members & easier testing / debugging.
- ▪ Named states: is core to the structure (see above why this is an advantage).
- ▪ Scalability: Statecharts scale well as complexity grows. You can easily manage distributed behavior through the actor model.
- ▪ Visualization: Logic can be visualized as a diagram (known as a statechart), acting as accurate documentation, making it easier to understand a system & acting as a communication language between coder / non-coder stakeholders.
- ▪ Exploration: The process of building a statechart encourages all states to be explored. This can prevent edge cases from being overlooked.
- ▪ Battle proven: 30+ years of refinement.
- ▪ Formalised logic: increasing a codebase's consistency.
- ▪ Steep learning curve: State machines are a significantly different way of thinking about state when compared to popular state management libraries such as Redux.
- ▪ Over-engineering: A state machine may seem like going overboard when a small amount of state management is required, such as a toggle that only requires a "on" & "off" state. This can be achieved with a small amount of code using React's "useState" hook. The counter-argument to this is, often what begins as simple state grows in complexity. State machines may be more work to begin with but less work at scale.
Events: when naming events performed by the user, accuratley describe what happened, not the intention of the user action.
Example, when a user clicks a sign in button on a form, instead of
signIn, name the event
Context: when naming an action that updates a machine's context, prefix the action with
Example, when an action changes
context.email, name the action
Storing state from a previous session & restoring it can improve the UX (User Experience). Different approaches to storing state:
Although any state stored here will not be available on different devices, it can be useful for websites that don't require sign-in (& therefore can't send state to be stored in a database).
Example, a Real Estate website that shows houses available to purchase.
If it had a min / max price filter, the values set could be stored in
localStorage & retrieved / applied each time the user returns to the website.
Similar to local storage except anything stored here will be cleared when the page session ends. Survives page reloads & restores.
Key / values stored in a URL. Useful when there is a requirement for a user to send a page address to another user in its current state.
The most feature rich & expensive storage approach.
|People to Follow|
|David Khourshid||Creator of XState. Founder of Stately|