reactjsreduxfrontendlogicflux

Redux business logic best practice


Im building a shopping cart with React and Redux and failing to understand the best practice flow.

My Cart ACTIONS:

export const addToCart = (product) => (dispatch, getState) => {
  let { products: cartProducts } = getState().cart;
  let { newCartProducts, totalPrice } = handleAddToCart(cartProducts, product);
  dispatch(
    add({
      products: newCartProducts,
      total: totalPrice,
    })
  );
};

Mock-Server handlers: (All the logic of updating the product is going here => my main question is if this is makes any sense.

export function handleAddToCart(cartProducts, currentProduct) {
  let idx = cartProducts.findIndex((p) => p.id === currentProduct.id);
  let productInCart = cartProducts[idx];
  if (productInCart) {
    let updatedProduct = {
      ...currentProduct,
      quantity: productInCart.quantity + 1,
      price:
        productInCart.price +
        applySale({
          ...currentProduct,
          quantity: productInCart.quantity + 1,
          currentTotal: productInCart.price,
        }),
    };
    cartProducts.splice(idx, 1, updatedProduct);
  } else cartProducts.push({ ...currentProduct, quantity: 1 });
  let totalPrice = cartProducts.reduce((acc, val) => (acc += val.price), 0);
  return { newCartProducts: cartProducts, totalPrice };
}

Cart reducer:


};
export default (state = DEFAULT_STATE, action) => {
  switch (action.type) {
    case "ADD_TO_CART":
      return {
        products: [...action.payload.products],
        total: action.payload.total,
      };

    default:
      return DEFAULT_STATE;
  }
};

As you see from the code, I kept action and reducer logic to minimum and let the handler manipulate data. only after the data is manipulated, I insert it to the state. After giving it thought, the reducer ADD_TO_CART is only symbolic because it gets an array and not an item so it can be actually a multi purpose reducer which is i think not so good. Would be great to hear more opinions.


Solution

  • We specifically recommend putting as much logic as possible into reducers, and treating actions as "events" that describe "what happened" with the minimal amount of data inside.

    Also, note that you should be using our official Redux Toolkit package, which will drastically simplify your Redux logic.