Benjamin Lee
Benjamin Lee

Reputation: 1224

Design question for Redux: When you want to make a Redux action to dispatch other Redux actions, should you?

I'm slowly adding Redux to React app. Not to all state, but to state that is consumed by many different components in the application.

There was function called saveOrRemoveNewItemOrBlankItem() that could be triggered by multiple events. I'd like to make this a single Redux action, or, at least I don't want to have to repeat the same logic everywhere the actions are dispatched, for example:

if(item.isBlank){
  store.dispatch(removeItem())
} else {
  store.dispatch(saveItem())
}

It would be better to just call one action (albeit one with a long name):

  store.dispatch(saveOrRemoveNewItemOrBlankItem())

I know it's possible (using thunk middleware) for one Redux action creator to dispatch other Redux actions, and am already doing this in places. However it isn't possible (or at least I don't know if it's possible) if I want to save time on boilerplate by using ReduxJS/Toolkit CreateSlice. I can accept more boilerplate, but I want to know... is it terribly 'un-Redux' for actions to call other actions (in this case for saveOrRemoveNewItemOrBlankItem to call either saveItem or removeItem conditionally) ? What's the proper design route to accomplish this? Surely not writing the same conditional logic in multiple places... Is there another layer that can offload this responsibility from the react components themselves? New(ish) to React and new to Redux. Less interested in solving this particular example than getting a good grasp of best practices. Thoughts, opinions, facts, expertise, brilliance appreciated... What am I missing?

Upvotes: 1

Views: 37

Answers (1)

HMR
HMR

Reputation: 39250

It is fine to combine actions in another action, you are right to not want this logic in your component. You don't need thunk to do this when using createSlice:

const slice = createSlice(/** stuff that creates slice */);
const sliceWithCombinedAction = {
  ...slice,
  actions: {
    ...slice.actions,
    commitItem(item) {
      return item.isBlanc
        ? slice.actions.removeItem()
        : slice.actions.saveItem();
    },
  },
};
export default sliceWithCombinedAction;

Upvotes: 1

Related Questions