This is my classification of different types of state management in React.
This is a native mechanism 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).
- 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.
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.
- 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.
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.
- Need to be aware of the fact that it is proxy and of the specific rules of this kind of state management.
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.
- A boilerplate-free API where shared state has the same simple get/set interface as React local state (useState/useAtom).
- recoil is not production ready yet (11/2021).
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.
- 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.
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.
- 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.