Raphaël Gomès
Raphaël Gomès

Reputation: 1028

React-Redux: Mutating the state to emulate action side-effects with redux-undo

I have a few fields that, when updated, change the href of an image (which is really an endpoint of an external API that generates a PNG based on text input).

When that image loads, it triggers an action to update another component to match the image size (that it can only get after the image has finished loading). I set redux-undo to exclude that action from the history since it's not a user action.

Here's my problem: When I do an action that does NOT trigger a change, then undo that action, the state is wrong since the size has changed in between user actions.

An idea I had was to mutate the state (yeesh):

In reducer

case 'UPDATE_TARGET_SIZE':
    /**
    *  HERE BE DRAGONS
    *  I am also mutating the current state since this action needs to
    *  NOT count as an user action
    */
    state.targetWidth = action.targetWidth
    state.targetHeight = action.targetHeight

    return {
        ...state
    }

While it works with no apparent drawbacks... it feels like a dirty hack. Is there another way of doing so or is it safe as long as I know why I'm mutating the state?

Can a lib like redux-saga help me? I admit I have not read its documentation since I am not making "real" API calls and I don't want to have an overkill solution.

Edit :

Here's a better example:

I type in a text input, which causes the href to change. A new image is loaded, which triggers the action that is excluded from the history. At that point, the history does not have the modification of that last action.

If I do an action that copies that part of the sate (in the right reducer), the state is fine. If I do an action that touches only another reducer, it will still be wrong.

So when I press undo, I undo to the wrong state. But if I get that action to mutate the state, then it's always valid.

Upvotes: 0

Views: 297

Answers (1)

Vladislav Ihost
Vladislav Ihost

Reputation: 2187

Can a lib like redux-saga help me? I admit I have not read its documentation since I am not making "real" API calls and I don't want to have an overkill solution.

Redux-saga allows to perform custom side effects and introduce process manager since it has own event loop. Applying to original task, saga can help with splitting action with request and response in time.

Typical use case is emitting action with postfix _REQUEST, like LOAD_IMAGE_REQUEST, which intercepts with saga manager and does not pass into reducers. Then after async operation is done, saga emits _SUCCESS or _FAILURE-like action, dependent on sucessfullity of operation. That actions passed into store and applied with reducers.

Also, there is ideology called optimistic update. In that case _REQUEST event passed into store, but if action is failed, saga sents compensating event, which rollback optimistic action

Upvotes: 1

Related Questions