Let's figure it out, An user performs a login submission, so app shows instead a Submit button a Spinner, a self contained state whose help us (isLoading).
Okay, when application send to saga login action we can pass a callback for set false loading state when login submission has successful or failure.
Some experts will say, manage loading state in reducers, but carry to all whole application loading state, for some specific action not sounds good.
The problem with callbacks is that the architecture doesn't guarantee that the callback gets called or that it won't get called multiple times. That is because redux actions are essential events - where each event can be handled by 0-n handlers (or sagas in our case).
Of course at the time of writing you know that that particular code is handled exactly once, but for anyone else this might be hard to grasp unless there are strict rules in the project how to handle this.
At the same time, you are right that putting local state to redux store isn't great. I usually deal with this by moving the data logic to its own structure. So e.g. loading collections of items from server is no longer local state of some component bur rather global data state that can be used and reused by multiple parts of the applications. This will also make it easier to have custom caching logic for the data cross whole application etc. However, some local component state in redux is still unavoidable for some specific backend calls.
In terms of future, I saw some attempts at useSaga
hook, which would work on top of local useReducer
hook and therefore local state, however the implementation for such logic is still limited because the current react hook api lacks certain functionality that is necessary to make sure this works well with react commit phase, render bail outs, reducer reruns etc.