Unobtrusive async action state tracking in React
Tracking an asynchronous action's pending state is a very common task in the process of building UIs. Most UIs will show a loading indicator while async data fetching is in progress and an error message if the async action fails, e.g. due to a network error. The question is: Can async action handling feel like setting up lightweight scaffolding without breaking into the code of the successful scenario? Similarly to JS error handling with try...catch...finally that can be easily added to the code of a successful case at any stage of the application development without major changes. Most ways to handle an async action's state are wired into complex libs either for data fetching (like Tanstack React Query, RTK Query) or shared state management (like Redux Toolkit). Introducing such libs and adapting the code to them (and to some arguably clumsy patterns at times [1+2, 3]) require sizable rewrites and don't quite feel like adding lightweight scaffolding to the existing code. In order to address my question, I ended up creating a small package called transient-state. It helps track async actions' state without breaking into the async actions' code and the app's shared state (or even requiring one). The async action's state can be used either locally or shared between multiple components equally easily. The package description outlines these and some other options in more detail.

Tracking an asynchronous action's pending state is a very common task in the process of building UIs. Most UIs will show a loading indicator while async data fetching is in progress and an error message if the async action fails, e.g. due to a network error.
The question is: Can async action handling feel like setting up lightweight scaffolding without breaking into the code of the successful scenario? Similarly to JS error handling with try...catch...finally
that can be easily added to the code of a successful case at any stage of the application development without major changes.
Most ways to handle an async action's state are wired into complex libs either for data fetching (like Tanstack React Query, RTK Query) or shared state management (like Redux Toolkit). Introducing such libs and adapting the code to them (and to some arguably clumsy patterns at times [1+2, 3]) require sizable rewrites and don't quite feel like adding lightweight scaffolding to the existing code.
In order to address my question, I ended up creating a small package called transient-state. It helps track async actions' state without breaking into the async actions' code and the app's shared state (or even requiring one). The async action's state can be used either locally or shared between multiple components equally easily. The package description outlines these and some other options in more detail.