reClicked
reClicked

Reputation: 25

Getting some kind of error in react redux with typescript while trying to dispatch a thunk action in a component

So hi guys, this is my first project where I try to use react-typescript with redux-toolkit and am getting an error:

Argument of type 'AppThunk' is not assignable to parameter of type 'AnyAction'. Property 'type' is missing in type 'AppThunk' but required in type 'AnyAction'.

Basically I just want to get data from cats public API, but it doesn't seem to work and I would really appriciate some help.

src/app/rootReducer.tsx

import { combineReducers } from "@reduxjs/toolkit";
import catsReducer from "../features/cat/catsSlice";

const rootReducer = combineReducers({
  cats: catsReducer,
});

export type RootState = ReturnType<typeof rootReducer>;

export default rootReducer;

src/app/store.tsx

import { configureStore, Action } from "@reduxjs/toolkit";
import { useDispatch } from "react-redux";
import { ThunkAction } from "redux-thunk";

import rootReducer, { RootState } from "./rootReducer";

const store = configureStore({
  reducer: rootReducer,
});

export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch();
export type AppThunk = ThunkAction<void, RootState, unknown, Action>;

export default store;

src/features/cat/catsSlice.tsx

import axios from "axios";
import { createSlice, PayloadAction } from "@reduxjs/toolkit";

import { AppThunk } from "../../app/store";
import { RootState } from "../../app/rootReducer";

export interface CatsState {
  cats: Array<Cat>;
  isLoading: boolean;
  error: CatsError;
}

export interface Cat {
  id: string;
  categories?: Array<any>;
  breeds: Array<any>;
  url: string;
  width: number;
  height: number;
}

export interface CatsError {
  message: string;
}

export const initialState: CatsState = {
  cats: [],
  isLoading: false,
  error: { message: "" },
};

export const catsSlice = createSlice({
  name: "cat",
  initialState,
  reducers: {
    setLoading: (state, { payload }: PayloadAction<boolean>) => {
      state.isLoading = payload;
    },
    setCatsSuccess: (state, { payload }: PayloadAction<Array<Cat>>) => {
      state.cats = payload;
    },
    setCatsFailed: (state, { payload }: PayloadAction<CatsError>) => {
      state.error = payload;
    },
  },
});

export const { setCatsSuccess, setCatsFailed, setLoading } = catsSlice.actions;

export const getCats = (): AppThunk => async (dispatch) => {
  try {
    dispatch(setLoading(true));
    const catsResponse = await axios.get(
      "https://api.thecatapi.com/v1/images/search?limit=8&size=small&order=random"
    );
    dispatch(setCatsSuccess(catsResponse.data));
  } catch (error) {
    dispatch(setCatsFailed({ message: "An Error occurred" }));
  } finally {
    dispatch(setLoading(false));
  }
};

export const catsSelector = (state: RootState) => state.cats;
export default catsSlice.reducer;

src/components/game/GameView.tsx

import React, { useEffect } from "react";
import { getCats, catsSelector, Cat } from "../../features/cat/catsSlice";
import { useSelector, useDispatch } from "react-redux";

const GameView: React.FC = (): JSX.Element => {
  const dispatch = useDispatch();
  const { cats, isLoading, error } = useSelector(catsSelector);

  useEffect(() => {
    dispatch(getCats());
  }, [dispatch]);

  return <>GameView</>;
};

export default GameView;

So as you can see I call the getCats() function in the useEffect hook, but it gets underlined with an error.

Any help would be appriciated! Thanks in advance!

Upvotes: 1

Views: 1847

Answers (1)

Sirine Dachraoui
Sirine Dachraoui

Reputation: 1

in 'store.tsx' useDispatch() doesn't take any

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

argument but you passed one in 'GameView.tsx':

 dispatch(getCats());

So you can fix this by adding an optional argument to useDispatch in 'store.tsx', so instead it will be :

export const useAppDispatch: (arg?:unknown) => AppDispatch = useDispatch

Upvotes: 0

Related Questions