saintyusuf
saintyusuf

Reputation: 504

React Redux Toolkit Doesn't Dispatch Async Thunk

I am using Redux/Toolkit and I want to use the Async Thunk for authentication processes. But it returns an error when I'm trying to dispatch the function.

What should I do in this case? It's the first time for me to use Async Thunk, so I don't have an idea how to face with this problem.

By the way I am using Typescript. So, I think this problem mostly about Typescript.

userSlice.tsx file:

import {createSlice, createAsyncThunk} from "@reduxjs/toolkit"
import {InterfaceUserSlice} from "../typescript/interfaceUserSlice"
import axios from "../axios"

export const UserLogin = createAsyncThunk("/users/authentication", async (user:{email:string,password:string}) => {
  try{
    const res = await axios.post("/users/authentication", user)
    ...
  } catch(err){
    ...
  }
})

const initialState:InterfaceUserSlice = {
  ...
}

const userSlice = createSlice({
  name: "user",
  initialState,
  reducers: {},
  extraReducers: (builder) => {}
})

export default userSlice.reducer

Login.tsx page file:

import React, {useState} from "react"
import { useDispatch } from "react-redux"
import { UserLogin } from "../redux/userSlice"

const Login = () => {

  const dispatch = useDispatch()

  const [email, setEmail] = useState<string>("")
  const [password, setPassword] = useState<string>("")
  
  function LoginRequest(){
    dispatch(UserLogin({email,password})) //This is the point that I have the error which says: "Argument of type 'AsyncThunkAction<void, { email: string; password: string; }, AsyncThunkConfig>' is not assignable to parameter of type 'AnyAction'."
  }
  
  return (
    ...
  )
}

export default Login

Upvotes: 0

Views: 1777

Answers (2)

Oleksandr
Oleksandr

Reputation: 64

If you use TypeScript you always should set return type and arguments for your asyncThunk in genric

export const UserLogin = createAsyncThunk<return type, arguments>("/users/authentication", async (user) => {
  try{
    const res = await axios.post("/users/authentication", user)
    ...
  } catch(err){
    ...
  }
})

And also you should create custom hook useDispatch and useSelector


import { useSelector, useDispatch, TypedUseSelectorHook } from "react-redux";

import type { RootState, AppDispatch } from "../redux/store";

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

export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;


And main reducer file should have such look:

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

import userleSlice from "./slice/userSlice";

export const store = configureStore({
  reducer: {
    user: userSlice,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

Upvotes: 1

Rashomon
Rashomon

Reputation: 6762

Try passing the type of the args to createAsyncThunk:

type ReturnedType = any // The type of the return of the thunk
type ThunkArg = { email:string, password:string } 

export const UserLogin = createAsyncThunk<ReturnedType, ThunkArg>("/users/authentication", async (user) => {
  try{
    const res = await axios.post("/users/authentication", user)
    ...
  } catch(err){
    ...
  }
})

Upvotes: 0

Related Questions