Where to put business logic in redux? action or store

hossein derakhshan picture hossein derakhshan · May 8, 2017 · Viewed 12.1k times · Source

i come from Reflux to Redux. in Reflux your business logic is exist only in store but in Redux its seems different..for example in "Redux" i have "async-action" and i implemented it with "redux-thunk" .

in one scenario i want to check something in my action and if that needed i send request to server and get some data. i this case i have to check my logic in my action and actually my business logic is exist in action and store together and its not good.. what is your solution?

for example i have checkbox and i check some condition and if the result is true i send a request to server here is my action code and as you see my business logic is on my Action and my Reducer:

export function onCheckboxClick({itemId}) {
  return (dispatch, getState) => {
      let state = getState().get('myReducer');

      let myConditionResult = state.get('foods').get(0).get('test');//for exmaple check some condition in my store

      dispatch({type: 'CHECKBOX_CLICK', itemId});// for change the checkbox checked

      if (myConditionResult) {
        myApi.deleteOrderItem({itemId}).then(()=> {
          dispatch({type: 'DELETE_ORDER_ITEM_FULFILLED', itemId});
        }).catch((err)=> {
          console.log(err);
          dispatch({type: 'DELETE_ORDER_ITEM_REJECTED', itemId});
        });
      }
   };
}

thanks in advance

Answer

markerikson picture markerikson · May 8, 2017

Quoting the Redux FAQ entry on "how to split business logic between action creators and reducers":

There's no single clear answer to exactly what pieces of logic should go in a reducer or an action creator.

If you put all the logic in the action creator, you end up with fat action objects that declare the updates to the state. Reducers become pure, dumb, add-this, remove that, update these functions. They will be easy to compose. But not much of your business logic will be there. If you put more logic in the reducer, you end up with nice, thin action objects, most of your data logic in one place, but your reducers are harder to compose since you might need info from other branches. You end up with large reducers or reducers that take additional arguments from higher up in the state.

It's valid to dispatch an action that gets ignored by the reducers, and it's also valid to inspect the state first and decide to not dispatch an action. Ultimately, it does come down to what you're comfortable with.