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

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

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

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

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.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

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

{{ parent.tldr }}

{{ parent.urlSource.name }}