Search code examples
javascriptreactjsasynchronousreduxdispatch

Question about Redux async operations with Thunk


I just recently got introduced to Redux and decided to learn how to implement it. At the moment I'm refactoring some of my previous studying-projects and implementing the global state logic provided by the tool. The thing is, I've recently stumbled upon the thunk middleware for async actions and got curious about something that's probably a simple concept misunderstanding but that I just can't get over.
So, why would I dispatch an async action? I just can't see the benefits of doing that way instead of waiting for the execution of whatever I'm doing and just then dispatch the action carrying the data I want.

Using a simple fetch call as an example, why would I not do the following:
->await fetch data
->dispatch fetched data

And instead do this:
->dispatch action
->await dispatch action

There's probably some use cases that I don't know of because for me, a beginner, sounds like extra code for something that maybe didn't require it? Idk.
Could someone help me? =)


Solution

  • Yep, as you found, that's Dan Abramov's original explanation of why something like the thunk middleware exists.

    I recently wrote a new Redux docs page on Writing Logic with Thunks, which goes into more detail on the purpose behind thunks and how to use them correctly. I'll quote from the "Why Use Thunks?" section:

    Thunks allow us to write additional Redux-related logic separate from a UI layer. This logic can include side effects, such as async requests or generating random values, as well as logic that requires dispatching multiple actions or access to the Redux store state.

    Redux reducers must not contain side effects, but real applications require logic that has side effects. Some of that may live inside components, but some may need to live outside the UI layer. Thunks (and other Redux middleware) give us a place to put those side effects.

    It's common to have logic directly in components, such as making an async request in a click handler or a useEffect hook and then processing the results. However, it's often necessary to move as much of that logic as possible outside the UI layer. This may be done to improve testability of the logic, to keep the UI layer as thin and "presentational" as possible, or to improve code reuse and sharing.

    In a sense, a thunk is a loophole where you can write any code that needs to interact with the Redux store, ahead of time, without needing to know which Redux store will be used. This keeps the logic from being bound to any specific Redux store instance and keeps it reusable.

    The Redux FAQ entry on "why do we use middleware for side effects?" links to additional information on this topic.