Search code examples
reactjsreact-reduxredux-toolkitredux-reducers

When two createSlice components have reducers with same name then, how to use work with `useDispatch`


Situation:

Let's say there are two Slice components defined using redux-toolkit. Because the data category is different, that is why each of them is stored in separate Slice component. Now there are some reducer functions with same name, the inside code of those functions are different because the data category is different but the name of reducer is same.

So In this case how could we use useDispatch?

Example:

Here is one createSlice Component, I used typescript here:-

import { createSlice } from "@reduxjs/toolkit";

type ImageStructure = {
   id: String;
   originalImage: String;
   croppedImage: String;
   zIndex: Number;
   posX: Number;
   posY: Number;
};
type PayloadStructure = {
   payload: {
      id: String;
      originalImage: String;
      croppedImage: String;
      zIndex: Number;
      posX: Number;
      posY: Number;
   };
};
type RemovePayload = {
   payload: {
      id: String;
   };
};
export const ImgSlice = createSlice({
   name: "image",
   initialState: Array<ImageStructure>(),
   reducers: {
      add: (state, action: PayloadStructure) => {
         state.push(action.payload);
      },
      remove: (state, action: RemovePayload) => {
         let arr = Array<ImageStructure>();
         for (let val in state) {
            if (state[val].id !== action.payload.id) {
               arr.push(state[val]);
            }
         }
         state = arr;
      },
   },
});
export const { add, remove } = ImgSlice.actions;
export default ImgSlice.reducer;

And Here is another createSlice component:-

import { createSlice } from "@reduxjs/toolkit";

type textStructure = {
   id: String;
   value: String;
   zIndex: Number;
};
type PayloadStructure = {
   payload: {
      id: String;
      value: String;
      zIndex: Number;
   };
};
type RemovePayload = {
   payload: {
      id: String;
   };
};
export const textSlice = createSlice({
   name: "text",
   initialState: Array<textStructure>(),
   reducers: {
      add: (state, action: PayloadStructure) => {
         state.push(action.payload);
      },
      remove: (state, action: RemovePayload) => {
         let arr = Array<textStructure>();
         for (let val in state) {
            if (state[val].id !== action.payload.id) {
               arr.push(state[val]);
            }
         }
         state = arr;
      },
   },
});
export const { add, remove } = textSlice.actions;
export default textSlice.reducer;

So in this above scenario, there could be more types of slices (say, Slice for svg, video, HtmlElement) with same reducer operations.

In this case, how can we use useDispatch inside our general react component?

Probable Approach :

One simple solution would be to obviously change the name of the reducers in both the Slice components. But I don't consider this as a scalable solution ( when there are multiple Slice components with same reducer names.


Solution

  • rename the action creators on import if you get a conflict:

    import { add as addText } from "./textSlice";
    import { add as addImage } from "./imageSlice";
    
    dispatch(addText(""))
    dispatch(addImage(img))
    

    Or you do it on export:

    export const { add: addText, remove: removeText } = textSlice.actions;