vladimirp
vladimirp

Reputation: 1554

How to implement optimistic state update / push using React, Redux and Redux-Saga

I am trying to implement optimistic state update so I update state immediately on update action and then perform undo & notify user if update request fails.

I have following worker and watcher sagas:

// Worker Saga
function* updateItem(action) {

    // Update state optimistically
    yield put({type: UPDATE_ITEM_OPTIMISTICALLY, payload: action.payload});

    try {
            const response = yield call(axios.post, `${API_URL}/updateItem`, action.payload);
        } catch (e) {
            // Undo state push
            yield put({type: UNDO_UPDATE_ITEM, payload: action.meta.currentState});
        }
}

// Watcher Saga
function* rootSaga() {
    yield takeEvery(UPDATE_ITEM, updateItem);
}

I am passing currentState in action so I can push back to it in case of request failure.

The problem with this approach is that UPDATE_ITEM_OPTIMISTICALLY action resolves before saga code and meta.currentState is then updated before its used within catch block.

Upvotes: 1

Views: 1306

Answers (1)

Alexander Vitanov
Alexander Vitanov

Reputation: 4141

Two solutions:

  1. Pass a deep copy of currentState to action payload (kind of slow)
  2. Keep a second field in your reducer called prevState and assign the props you need from current state to it, then use it in your saga

Upvotes: 2

Related Questions