Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Practical ReactJS and Redux — Optimistic Updates (Part 3)

DZone's Guide to

Practical ReactJS and Redux — Optimistic Updates (Part 3)

This is the third in a series of blog posts about real-world ReactJS usage and what we've learned scaling our app at Threat Stack. Specifically, this is a quick follow-up that provides tips on how to achieve optimistic updates and rollbacks with what we've worked on in parts 1 and 2 of this series.

· Web Dev Zone
Free Resource

Tips, tricks and tools for creating your own data-driven app, brought to you in partnership with Qlik.

Optimistic_Updates.png

This is the third in a series of blog posts about real-world ReactJS usage and what we've learned scaling our app at Threat Stack. Specifically, this is a quick follow-up that provides tips on how to achieve optimistic updates and rollbacks with what we've worked on in parts 1 and 2 of this series.

We're still making sure to answer these questions:

  • How does it help with ease of development?
  • How fast can new team members understand what's going on?
  • How fast can you figure out if something is broken?

This makes use of the CallApiMiddleware shown in Part 1 of this series.

Values passed in the action payload propagate into the reducer.

This can be used for optimistic updates and rollback on errors.

Sure, you could put middleware in place to handle it. But. I think being more declarative here is a bigger win.

ItemActions.js

export function updateItem ({ item, prevItem }) {
  return {
    types: [ UPDATE_ITEM, UPDATE_ITEM_SUCCESS, UPDATE_ITEM_ERROR ],

    callAPI: () => Api.updateItem(item),

    effect ({ dispatch, state, type }) {
      if (type === UPDATE_ITEM_ERROR) {
        // dispatch a notification action which should update
        // state and show a notification somewhere 
        dispatch(showErrNotification('Error updating item'));  
      }
    },

    // prevItem gets passed along with each `type` (request, success, fail)
    payload: {
      item,
      prevItem
    }
  };
}

ItemReducer.js

export default function (state = initialState, action) {
  const { payload } = action;

  switch (action.type) {

    // NOTE: `UPDATE_ITEM_SUCCESS` is not used

    // We'll update the state tree using
    // what was sent to the server by pulling it from `payload`

    case UPDATE_ITEM:
      return {
        item : payload.item,
        err  : null
      }

    // If there was an error, we can revert the state to the previous item
    case UPDATE_ERROR
      return {
        item : payload.prevItem, 
        err  : action.err
      }

    default:
      return state;
  }
}

Where We Ended Up...

There are libraries and middleware to account for this type of thing.

But, I think the real win here comes from using the same building blocks, in this case, payload, to accomplish different things.

It becomes clear when reading the code what's going on when you're passing a prop called prevItem along.

P.S. Hack the Planet

Explore data-driven apps with less coding and query writing, brought to you in partnership with Qlik.

Topics:
updates ,javascript ,react js ,redux ,rollbacks

Published at DZone with permission of Cristiano Oliveira, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}