Thank you for this article. I've come to almost all the same conclusions as you have, and I just now found your article. I have one question though, that I haven't found a clean/elegant answer to. While I agree that conditionally loading data should be done in an effect, and not in a component, this makes handling loading flags more difficult. I see two options for handling loading flags - either add the same logic in the effect to the reducer as well, or somehow dispatch a new action that says the data is definitely loading (I haven't found a clean way to do this).
I'm speaking specifically to the scenario where we dispatch something like "MemberActions.memberListComponentInitialized" where an effect conditionally loads Members based on whatever. You can't have a reducer listening to that same action which automatically sets a loading flag because the memberListComponentInitialized action may or may not actually trigger loading that data.
That is the last discomfort I've seen with this approach, and I'd love to hear your solution.
In case you visit these comments again, let me spell out the issue with the code you show above and loading flags. I'm still curious how you actually deal with those in your real code.
let's assume the songs are already loaded, and the user navigates to the songsPage
you dispatch songsPageActions.opened when the songs page is opened
the reducer for songsPageActions.opened sets isLoading = true
any spinny loading gifs subscribed to isLoading start spinning - telling the user that songs are being loaded
an effect handling songsPageActions.opened gets stopped at the filter...
filter(([, songs]) => !songs),
and neither songsApiActions.songsLoadedSuccess nor songsApiActions.songsLoadedFailure gets dispatched, therefore isLoading never gets set to false. I'm assuming the reducers for both of the above actions are where you set isLoading = false
the loading spinny gifs continue to spin... forever... and ever... because they never know when the data is loaded
You cannot use the songsPageActions.opened to set isLoading = true because the effect that actually calls an api to load the songs CONDITIONALLY calls that api to load the songs. Without the same condition in your reducer (yuck) you don't know if songs are actually being loaded.
Once again, I like everything you evangelize in your post here, but I have no answer (and I don't see you presenting a working answer) to handling loading flags.
Additionaly, if you have a complex condition that is repeated in the effect as well as in the reducer, you can move it to a helper function and reuse it in both places.
Thanks a lot! I'm going to try this. I like the idea of making the condition something reusable. I also have come to the conclusion that I don't actually need these conditions as often as I thought. In reality, I rarely stop the loading of something because it's already loaded. The actions that cause something to load almost always cause them to load. On the rare occasion I really need a conditional load, this sounds like a clean way to handle it.
Still hoping for some experienced advice on this. Everything you've written here resonates with me, and seems very elegant for all the purposes of software maintenance. I'm just having trouble coming up with an elegant solution to loading flags. It seems like a bad idea to force logic into reducers, logic that should only be inside effects, in order to figure out if a particular action is actually triggering the loading of specific data. I also cannot figure out how to deterministically communicate via the store that data is definitely loading, but I think this is probably possible.
Thank you for this article. I've come to almost all the same conclusions as you have, and I just now found your article. I have one question though, that I haven't found a clean/elegant answer to. While I agree that conditionally loading data should be done in an effect, and not in a component, this makes handling loading flags more difficult. I see two options for handling loading flags - either add the same logic in the effect to the reducer as well, or somehow dispatch a new action that says the data is definitely loading (I haven't found a clean way to do this).
I'm speaking specifically to the scenario where we dispatch something like "MemberActions.memberListComponentInitialized" where an effect conditionally loads Members based on whatever. You can't have a reducer listening to that same action which automatically sets a loading flag because the memberListComponentInitialized action may or may not actually trigger loading that data.
That is the last discomfort I've seen with this approach, and I'd love to hear your solution.
In case you visit these comments again, let me spell out the issue with the code you show above and loading flags. I'm still curious how you actually deal with those in your real code.
You cannot use the songsPageActions.opened to set isLoading = true because the effect that actually calls an api to load the songs CONDITIONALLY calls that api to load the songs. Without the same condition in your reducer (yuck) you don't know if songs are actually being loaded.
Once again, I like everything you evangelize in your post here, but I have no answer (and I don't see you presenting a working answer) to handling loading flags.
Hi Tim!
You can do something like this:
Additionaly, if you have a complex condition that is repeated in the effect as well as in the reducer, you can move it to a helper function and reuse it in both places.
Thanks a lot! I'm going to try this. I like the idea of making the condition something reusable. I also have come to the conclusion that I don't actually need these conditions as often as I thought. In reality, I rarely stop the loading of something because it's already loaded. The actions that cause something to load almost always cause them to load. On the rare occasion I really need a conditional load, this sounds like a clean way to handle it.
Still hoping for some experienced advice on this. Everything you've written here resonates with me, and seems very elegant for all the purposes of software maintenance. I'm just having trouble coming up with an elegant solution to loading flags. It seems like a bad idea to force logic into reducers, logic that should only be inside effects, in order to figure out if a particular action is actually triggering the loading of specific data. I also cannot figure out how to deterministically communicate via the store that data is definitely loading, but I think this is probably possible.
dev.to/markostanimirovic/comment/2...