As Magento Progressive Web Applications (PWAs) grow in the number of features and pages, managing the state can become a difficult task, as in many other complex PWAs.
Managing the global state and local state may require different techniques to achieve smaller complexity, but also to achieve scalability.
Managing The Global State
Managing the global state, or a cross-page state is useful when you for example want to keep the client logged in when navigating through the application, or when you want to keep your items in a cart when navigating through products or a blog.
To achieve smooth performance and a good user and developer experience, we are using the following tools to manage the global state.
Persistent Global State
Persistent global state is needed for things such as authentication, or visitor’s view preferences. LocalStorage is mainly being used for its simplicity and browser compatibility. In PWA Studio or some other Magento PWAs, LocalStorage is used to hold the authentication key which is then sent in HTTP requests to authenticate the logged-in customer. The second most common use-case for LocalStorage is to improve second page load by storing GraphQL responses in a temporal cache.
The URL may contain query parameters that are then accessible anywhere in the application. The most common use-cases are pagination, filter preferences, or sorting preferences.
Non-Persistent Global State
Redux or React Context are the most common tools used in React applications to manage this kind of state. Opening up a search bar, minicart, or performing a search are actions that need to be reflected across the whole UI, but after a page reloads we do not need to return to the previous state before we did the reload.
React Context is now considered stable and is slowly being widely used in React PWAs instead of other global-state-management libraries like Redux, MobX, or Flux. The main advantage of React Context is that it is built-in to React, is easy to use, and works well for the most common use-cases.
Managing The Local State
Toggling on a checkbox, hovering over a button, opening up an accordion, … all those actions are local and usually don’t need to be synchronised across the whole application. Their impact is only local, and React is offering us a great tool to manage this kind of state.
Since React introduced hooks, managing this kind of a state has become an easy, day-to-day thing for React developers. The `useState`, or `useContext` hooks provide most of the needed functionality, are easy to use, and reuse.
When Local Needs To Be Global
This happens in all modern web applications and Magento PWAs are no different. When using React and writing reusable components and reusable logic, it should not be difficult to change or propagate local state into global state. React’s focus on changeability is exceptionally handy when developing something new where unexpected requirements may occur. By building your own reusable hooks and leveraging the React Context ability to create a global state you should be finished in no time.
Synchronisation of the local and global state is required in almost every medium to large scale web application. For example, when you click on a “Add to cart” button, the button may become disabled while the minicart details may be getting updated too. Both of those UI areas are visually not connected, but they need to share the same state at the same time.
React allows us to create highly reusable components which can be used to propagate state changes up the virtual component tree. Those reusable components can receive external properties from any other smart component and propagate changes to the smart components by calling appropriate functions provided by the smart components. Those smart components can be then connected to any other reusable components to achieve the needed results.
It Can Only Get Better
State management is becoming more and more complex, as web applications are growing in size. As further developments on React continue, we could expect easier to use tools to become available to speed up the development.