Advanced Redux Action Types

Zack Argyle
Netscape
Published in
3 min readApr 16, 2016

The Javascript ecosystem has flourished under its flags of freedom and flexibility, but for large-scale projects it introduced a gnarled concoction of issues. Redux attempts to solve some of those issues by introducing a sane way of making changes to the state of your page via actions. It’s simple really: fire an action that changes the virtual state of the page, and let the view update itself.

Easy.

Problem is…life aint that easy. Simple synchronous actions aren’t enough to handle the deluge of action types that need to take place in real-world applications. The answer is middleware. We’re going to go over a few vital redux middlewares that provide even more power to your action creators. Redux is like carbon. Alone it is great, but when you mix it with other molecules you can truly start to appreciate the creations that it makes possible.

Thunk Actions: redux-thunk

This was, and still is, the most crucial middleware for any serious redux app. Thunk actions are essentially functions to be called later on down the road. In a world of synchronous actions, thunk actions allow you to very simply create asynchronous actions by dispatching a function instead of an object. Here is the most simple example (from the docs).

function incrementAsync() {
return dispatch => {
setTimeout(() => {
dispatch(increment());
}, 1000);
};
}

The other secret that thunk actions also enable is conditional actions. This allows your application to simplify and focus on readability. Again, here is a snippet from the docs.

function incrementIfOdd() {
return (dispatch, getState) => {
const { counter } = getState();
if (counter % 2 === 0) {
return;
}
dispatch(increment());
};
}

Promise Actions: redux-promise

But what if you need to fire an action when another thunk action completes? Promises are, of course, the go-to solution for such situations. This middleware encourages the use of redux-actions, which is a library for easily creating standard flux actions. It is, however, not a requirement. Here’s what it looks like in action. Each of these examples will dispatch an action with the Promise result as the payload as soon as the Promise resolves.

// With the ES7 async/await pattern
const fetchThing = createAction('FETCH_THING', async id => {
const result = await fetch('...');
return result.json();
});
// With standard Promise syntax
const fetchThing = createAction('FETCH_THING', id => {
return fetch('...').then(result => result.json());
});

The main idea behind adding redux-promise is to standardize all actions within your application. You could call fetch directly within your app, but as it grows it becomes increasingly difficult to identify data flow. Normalizing all state changing events to be redux actions increases readability and debuggability.

Queued Actions: redux-async-queue

Similar to the problems solved by Promise middleware, queued actions allow the application to assure execution order of asynchronous thunk actions. The middleware provides a ‘next’ method as an argument to the thunk callback. When called, it will dequeue the next waiting action. Here is a colorful example from the docs.

function queueMakeBurger(burgerStyle) {
return {
queue: MAKE_BURGER,
callback: (next, dispatch, getState) => {
getIngredients(burgerStyle).then(ingredients => {
dispatch(makeBurger(ingredients));
next();
});
}
}
}

Debounced Actions: redux-debounce

There comes a time in every application where you need to debounce something, and it’s almost always your stupid input fields or event logging. Instead of debouncing manually this middleware allows you to debounce it from within Redux itself. So you can fire off as many actions as you want and be sure that the state will only update after the wait period. I haven’t used this one myself, and may have chosen a different API implementation, but the idea is solid. Here is an example from the docs, where ‘simple’ is the key to the configured debouncer.

const debouncedAction = () => ({
meta: { debounce: 'simple' },
type: 'TEST'
});

There you have it. Some advanced Redux action types that should be helpful as you go forth and build. I’d love to hear about any other middlewares you have used in your projects that you’ve found invaluable.

  • Thunk Actions
  • Promise Actions
  • Queued Actions
  • Debounced Actions

Shoutout to Dan Abramov, Andrew Clark and Neil Kistner, the authors of the mentioned middlewares.

--

--