Skip to content

Example redux modules

Haz edited this page May 10, 2017 · 24 revisions

There're a bunch of redux modules already on the example app. Here's an explanation of each of them.

async is responsible for handling "pseudo-asynchronous" action creators. It listens to action creators with *_REQUEST type dispatched with meta.done own property. Then, it returns a promise that will be fulfilled or rejected when the equivalent *_SUCCESS or *_FAILURE actions are dispatched.

Consider the following action creators:

export const resourceCreateRequest = (entity, data, done) => ({
  type: 'RESOURCE_CREATE_REQUEST',
  payload: {
    data,
  },
  meta: {
    entity,
    done,
  },
})

export const resourceCreateSuccess = (entity, detail, request) => ({
  type: 'RESOURCE_CREATE_SUCCESS',
  payload: detail,
  meta: {
    entity,
    request,
  },
})

When dispatching resourceCreateRequest, resource saga will take it and make the http request, dispatching resourceCreateSuccess when it's done. Since the request action had a meta.done property, the async middleware will handle it and return a promise from dispatch:

// on some container
store
  .dispatch(resourceCreateRequest({ title: 'Hello, World!' }))
  .then((detail) => {
    console.log('Yay! Resource was created!', detail)
  })

You can also provide the done callback function. In this case, the async middleware will not have effect:

// It will not return a promise since you are providing a callback
store.dispatch(resourceCreateRequest('posts', {
  title: 'Hello, World!',
}, (err, detail) => {
  if (err) {
    return console.error(err)
  }
  return console.log('Yay! Resource was created!', detail)
}))

Solving race conflicts

That works great for most cases. But, if you need to handle multiple simultaneous async actions with the same type, the first one that resolves will fulfill all the other actions. That happens because it has only the type (e.g. RESOURCE_CREATE_REQUEST) to match with the response action (e.g. RESOURCE_CREATE_SUCCESS).

To solve it, the async middleware also adds a meta.key property to the request action. If you need to use that, just grab it from the request action and pass to the response action so async could handle it.

Clone this wiki locally