In redux we have multiple reducers that handle state as whole. In a todo app, todos are a slice of the state, but they are not always the entire state. In your case, your app's state consists of two entities, the todos, and the status of the loading.
With the above in mind, you can have one reducer that handles the todods. It will take care of loading all the items, or updating an item, or deleting one. In other words, this reducer is only concerned with the state of the todos, but it does not care about where you are in your lading process of an ajax call.
For the loading process you can create another reducer. This reducer knows nothing about your todos and it can really work for any sort of data that your app manages. All this reducer is worried about is if we are currently in the middle of an async ajax call. If we are then we can set some bool like isLoading
to true, and when the async call is either done or errored out we just set it to false. Then any component that wants to display some spinner while loading only needs to subscribe to state changes of this loading reducer.
This is the way I have implemented this feature in multiple production projects at my work. This is by no means the only way, or the best way, its just a way that I know works.
EDIT: The above works well for a more general loader across the site, however the OP wants to know how to make each individual item show a loader when some async call is happening that involves only that item.
The approach I would take is as follows. Instead of having only one array in state that keeps track of the todos, we now have 2 arrays in state. One array keeps track of the data, and the other keeps track of the data as it relates to UI. In other words, the array that keeps track of data will know nothing about isLoading
since this is a UI related prop, but the other array will keep track of all the todos as they relate to UI. This way when looping through each todo during the render faze, we can look to see what the isLoading status is of this exact todo in the UI related array in state, and if isLoading
is true then we display a spinner on this specific todo.
This gives a nice seperation of concerns. The array that is keeping track of data does not need to worry about UI at all. but we still get the benefit of having an individual spinner for item in the list.