Redux middleware is half working but not fully can

2020-05-06 23:16发布

问题:

I have some simple middleware that is kind of working but also not working

basically I have a list of users and I am trying to delete one. and then sync it up with firebase. all is well.

I'm adding some middleware so that when a user deletes one it asks if you are sure? (just using a simple alert for now). if you click cancel, it doesn't delete. if you click ok it does

so far, that is working but because of my action creators it still carrying on and deleting the user. here is some code:

// click to delete user

  <button
    onClick={() =>
      this.props.deleteUserFromStoreThenUpdateFirebase(user)
    }
 >

calls this method I think something funky is going on here, basically it shouldn't call the deletedUserFromFirebase method if I hit cancel

export const deleteUserFromStoreThenUpdateFirebase = user => {
  return (dispatch, getState) => {
    return dispatch(deleteUser(user)).then(() => {
      return deleteUserFromFirebase(user);
    })
  };
};


export const deleteUser = user => {
  return async dispatch => {
    dispatch({ type: DELETE_USER, user: user, reqConfirm: true });
  };
};

middleware:

const confirmMiddleware = store => next => action => {
    if(action.reqConfirm){
      if(confirm('are you sure?')){
        next(action)
      }
    }
    else {
      next(action)
    }
}

回答1:

I also think that confirmation actions should be [only] role of the UI.

Redux store can (should?) be treated like API - request (action) > response (changed state). Are you sending request to an API and waiting to confirmation message? It would be at least strange.

But I see even more than some sense in this idea. Centralised confirmation element can have a similiar role to toasts/snackbar messages.

Problem #1: There is a strict separation between UI and store logic - you can't use middleware to show dialog. But you can change state which can used in UI to show confirmation dialog.

Problem #2: There is no simple if/then/return chain of actions, you have to buffer an action and run it after confirmation (receiving 'confirm' action) or drop it on cancel. Yes, it can be done as middleware.

IDEA: Action dispatched as requiring confirmation is saved in buffer. You can then change action type to CONFIRM_SHOW - state will be changed, props passed, modal dialog can be shown.

On CONFIRM_OK run buffered action, next steps will be common with CONFIRM_CANCEL: clear buffer and hide modal. It could be even one value - buffer can be a modal flag (empty - hide, defined - show) dervied in mapStateToProps.

To be fully usable there should be an option to pass custom confirmation message along with reqConfirm.