-
Notifications
You must be signed in to change notification settings - Fork 19
Optimistic Updates
We believe server response via api calls should be the single source of truth when rendering components. However, it is often times overfetching to re-fetch everything after each user interaction. Thus, techniques like optimistic update are used to reduce bandwidth consumption and provide more interactiveness for your web applications.
Optimistic updates are achievable with redux-api-call using updater function. Let's take a look at the following example:
// EXAMPLE: optimistic updates (experimental feature)
const { updater, dataSelector } = makeFetchAction('LIST_ALL_TODOS', () => ({
method: 'GET',
endpoint: '/api/todos/'
});
const { actionCreator } = makeFetchAction('MARK_TODO_AS_DONE', (id) => ({
method: 'PUT',
endpoint: `/api/todo/${id}`,
body: JSON.stringify({ done: true }),
headers: { 'content-type': 'application/json' }
}));
// create a thunk action creator
const markAsDone = (id) => (dispatch, getState) => {
// start the actual request PUT /api/todo/{id}
dispatch(actionCreator(id));
// optimistic update to todos list
// let assume allTodos is stored as a hash of id => todo
const allTodos = dataSelector(getState());
// we expect after submitting, attribute done of the given todo must become true
const optimisticTodo = Object.assign({}, allTodos[id], { done: true });
const optimisticTodoList = Object.assign({}, allTodos, { [id]: optimisticTodo });
// this will replace your latest result from API with the optimistic todo list from above.
// if the actual request has the same result with optimistic values, nothing will change in UI.
// otherwise, next server response will overwrite optimistic values as expected
dispatch(updater(optimisticTodoList);
};
// usage: mark todo with id of 42 as done
store.dispatch(markAsDone(42));updater function acts as a action creator to replace server-responded data with your prediction how those data should look like after an real update. Whenever an action returned from updater is dispatched, corresponding redux store will remember the payload and the next time you call dataSelector, that payload will be returned.