skip to Main Content

In my slice, I have defined the action to be as follows:
https://github.com/jasonabanico/RedGranite/blob/main/src/Client/RedGranite.Client.Web/src/app/containers/ItemPage/itemPageSlice.ts

export const addItem = createAsyncThunk(
    'itemPage/addItem',
    async (itemInput: ItemInput) => {
        return await itemService
            .addItem(itemInput)
            .catch((err: any) => {
                console.log("Error:", err);
            });
    },
)

I have also defined useAppDispatch as:
https://github.com/jasonabanico/RedGranite/blob/main/src/Client/RedGranite.Client.Web/src/app/hooks.ts

export const useAppDispatch = () => useDispatch<AppDispatch>();

I use both of the above like so:
https://github.com/jasonabanico/RedGranite/blob/main/src/Client/RedGranite.Client.Web/src/app/containers/ItemPage/addItemPage.tsx

const dispatch = useAppDispatch();
...
dispatch(addItem(itemInput));

I am getting the following error:

TS2345: Argument of type ‘AsyncThunkAction<void | AddItem, ItemInput, AsyncThunkConfig>’ is not assignable to parameter of type ‘AnyAction’.
21 | longDescription
22 | };

23 | dispatch(addItem(itemInput));
| ^^^^^^^^^^^^^^^^^^
24 | };

What is wrong with my definitions? Why can’t I use addItem in dispatch?

UPDATE:

Code in repo updated to this, but getting same error.

export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();

UPDATE:

To replicate in Codesandbox.

  • Open terminal
  • cd src
  • cd Client
  • cd RedGranite.Client.Web
  • npm install
  • npm run build
  • see build error

2

Answers


  1. According to current documentation it would seem your useAppDispatch and useAppSelector hooks aren’t quite right.

    • For useSelector, it saves you the need to type (state: RootState) every time

    • For useDispatch, the default Dispatch type does not know about thunks. In order to correctly dispatch thunks, you need to use the
      specific customized AppDispatch type from the store that includes
      the thunk middleware types, and use that with useDispatch. Adding a
      pre-typed useDispatch hook keeps you from forgetting to import
      AppDispatch where it’s needed.

      import { useDispatch, useSelector } from 'react-redux'
      import type { RootState, AppDispatch } from './store'
      
      // Use throughout your app instead of plain `useDispatch` and `useSelector`
      export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
      export const useAppSelector = useSelector.withTypes<RootState>()
      

    Update your src/Client/RedGranite.Client.Web/src/app/hooks.ts file to the current suggestion:

    import { useDispatch, useSelector } from 'react-redux';
    import type { RootState, AppDispatch } from './store';
    
    // Use throughout your app instead of plain `useDispatch` and `useSelector`
    export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
    export const useAppSelector = useSelector.withTypes<RootState>();
    
    Login or Signup to reply.
  2. It seems you are returning wrong data in your action function.
    So I think it should be like this:

    
    export const addItem = createAsyncThunk(
      "itemPage/addItem",
      async (itemInput: ItemInput, { rejectWithValue }) => {
        try {
          const data = await itemService.addItem(itemInput);
          return data;
        } catch (error: any) {
          // if there is an error, it would get rejected status in your extraReducer function
          if (error.response.data) return rejectWithValue(error.response.data);
        }
      }
    );
    
    

    Hope this can be helpful.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search