React: different types of state management
Tags: react, redux, apollo, jotai
Published: 2021-11-25 13:15:50

This is my classification of different types of state management in React.

&nbsp;

### 1. React context
*This is a [native mechanism](https://reactjs.org/docs/context.html) in react core.* 
Actually context is not exactly state management tool, it is kind of Dependency Injection. Context provides a way to pass data through the component tree without having to pass props down manually at every level. It is best used when you have some value that is rarely changed and you want to make it accessible to a portion of your React component tree (without passing that value down as props through each level of components).

Issues: 
* Making a change in some inner param of the state object that is stored in a context will rerender all the consumers of this context (even if they don't use this specific param). So context can only store a single value, not an indefinite set of values each with its own consumers.
* Context hell - using this approach as a state management tool will lead us to many nested contexts in different places in react tree.

&nbsp;

### 2. Global store
[*redux*](https://redux.js.org/), [*zustand*](https://zustand.surge.sh/)
Centralized application state and logic based on Flux architecture model by Facebook. The major idea behind Flux is that there is a single-source of truth (the store) and it can only be updated by triggering actions. The actions are responsible for calling the dispatcher, to which the store is subscribed for changes and updates.

Notes: 
* *redux:* One of the most known state management solutions in JS world. Lots of boilerplate - actions, reducers, selectors.
* *zustand:* A small, fast and scalable state-management solution using simplified flux principles. It requires much less boilerplate code due to its opinionated approach. In zustand the store doesn't have to be global, but still..
* Complicated store mutation. Need to create immutable path when modifying some nested state. Using utils like *immer* or *immutable* may help to manipulate the store.

&nbsp;

### 3. Magic store 
[*MobX*](https://mobx.js.org/), [*Valtio*]( https://github.com/pmndrs/valtio)
This type of state management solution wraps the store params in a proxy. So you deal with a proxy and not with the object directly. You perform some simple operation and **_magically_** behind the scene, the shared state changes.

Notes: 
* Need to be aware of the fact that it is proxy and of the specific rules of this kind of state management.

&nbsp;

### 4. Atomic model 
[*recoil*](https://recoiljs.org/), [*jotai*](https://jotai.org/)
A bottom-up approach to React state management with an atomic model. Atoms are units of state. They're updateable and subscribable. One can build state by combining atoms and renders are optimized based on atom dependency. This solves the extra re-render issue of React context and eliminates the need for the memoization technique.

Notes:
* A boilerplate-free API where shared state has the same simple get/set interface as React local state (useState/useAtom).
* *recoil* is considered to be experimental project (02/2023).

---
&nbsp;

## Network request global cache

These libraries help to perform network requests in React. One of the main features of these libraries is to keep the requests in cache. So next time you perform the same request, you will get a cached response. It doesn't metter where in the react tree you perform this request, the cache is global and behaves like a global state management solution for network requests.

&nbsp;

### 5. REST cache 
[*react-query*](https://react-query.tanstack.com/), [*swr*](https://swr.vercel.app/)
These libraries have many features based on their sophisticated cache mechanism like: request retry, revalidation, polling, prefetching and more.

Notes:
* *SWR* (stale-while-revalidate) is a strategy to first return the data from cache (stale), then send the fetch request (revalidate), and finally come with the up-to-date data.

&nbsp;

### 6. GraphQL cache
[*apollo*](https://www.apollographql.com/), [*urql*](https://formidable.com/open-source/urql/)
These are graphql clients that keep cache of graphql network requests. Their behavior is similar to the REST cache solutions from above. The cache is global and behaves like a global state management solution for graphql requests.

Notes:
* Apollo uses normalized cache which reduces data redundancy but is more complicated.

---

P.S. In my latest project I chose jotai, react-query and apollo.
`:)`