Search code examples
reactjsreact-nativereduxreact-reduxredux-thunk

What is the difference between using redux-thunk and calling dispatch() directly


I'm in the learning phase of understanding redux state management and still trying to negotiate the bewildering jungle of boilerplate code and middleware, much of which I'm taking on faith as 'good medicine'. So I hope you'll bear with me on this perhaps rudimentary question.

I know that redux-thunk allows action creators to proceed asynchronously and dispatch a regular action at a subsequent time. For example, I can define a thunk action creator in my actions.js:

export function startTracking() {
  return (dispatch => {
     someAsyncFunction().then(result => dispatch({
       type: types.SET_TRACKING,
       location: result
     }))
  })
}

And invoke it from within a React component like so:

onPress={() => this.props.dispatch(actions.startTracking())}

My question is, what advantage does the above code confer over simply dispatching an action from inside an asynchronous callback?

import { store } from '../setupRedux'
...

export function startTracking() {
 someAsyncFunction().then(result => {
   store.dispatch({
     type: types.SET_TRACKING,
     location: result
   })
 })
}

which I would invoke inside my component

onPress={() => actions.startTracking()}

or even

onPress={actions.startTracking}

Is there anything problematic with accessing store directly via an import as I'm doing in the 2nd example?


Solution

  • There is nothing wrong doing so. From the redux-thunk page:

    If you’re not sure whether you need it, you probably don’t.

    The creator of redux explain the advantage of using it here:

    This looks simpler but we don’t recommend this approach. The main reason we dislike it is because it forces store to be a singleton. This makes it very hard to implement server rendering. On the server, you will want each request to have its own store, so that different users get different preloaded data.

    Basically, using redux-thunk will save you the store import in each action creator file and you will be able to have multiple store. This approach also give you the opportunity to write a little bit less code and to avoid spaghetti code. Many redux developer don't like to import the store and to manually dispatch because it can create circular dependencies if the code is badly separated (importing an action name from the action creator file in the reducers file and importing the store from the reducers file in the action creator file). Also, dispatching directly an action like that might break the middleware workflow, ie: the action might not be handled by a middleware.

    But honestly, if you don't see an advantage to it yet, don't use it. If one day you have trouble with async actions, redux-thunk might be the answer.