0

I tried making a user authentication using redux toolkit in Nextjs with Typescript but I keep getting the following error when dispatching an action.

Type error: Argument of type 'AsyncThunkAction<any, SigninParams, AsyncThunkConfig>' is not assignable to parameter of type 'AnyAction'.

This is my signin.tsx file

import { useState } from 'react'
import { useDispatch } from 'react-redux'
import { getUser } from '../../store/slices/userSlice'

const Signin = () => {
    const dispatch = useDispatch()

    const [userData, setUserData] = useState({
        email: '',
        password: '',
    })

    const signinHandler = async (e: any) => {
        e.preventDefault()
        dispatch(getUser({ userData }))
    }

    return (
        <div className='flex items-center justify-center w-screen h-screen'>
            <form
                onSubmit={signinHandler}
                className='border p-5 flex flex-col items-center justify-center'>
                <input
                    type='email'
                    onChange={(e) =>
                        setUserData((prev) => ({
                            ...prev,
                            email: e.target.value,
                        }))
                    }
                />
                <input
                    type='password'
                    onChange={(e) =>
                        setUserData((prev) => ({
                            ...prev,
                            password: e.target.value,
                        }))
                    }
                />
                <button>Signin</button>
            </form>
        </div>
    )
}

export default Signin

This is what the userSlice.ts file looks like

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import dbConnect from '../../lib/dbConnect'
import axios from 'axios'

export interface UserState {
    status: 'idle' | 'loading' | 'failed'
    user: object
    error: string | null | object
}

interface SigninParams {
    email: string
    password: string
}

// Default state object with initial values.
const initialState: UserState = {
    status: 'idle',
    user: {},
    error: null,
} as const

// Thunks
export const getUser = createAsyncThunk(
    'user/signin',
    async (params: SigninParams) => {
        await dbConnect()
        const { email, password } = params
        
        const config = {
            headers: {
                'Content-Type': 'application/json',
                Accept: 'application/json',
            },
        }
        const { data } = await axios.post(
            '/api/signin',
            { email, password },
            config
        )

        localStorage.setItem('userInfo', JSON.stringify(data))
        localStorage.setItem('token', data.token)

        return data
    }
)

//Slice
export const userSlice = createSlice({
    name: 'user',
    initialState,
    reducers: {},
    extraReducers: (builder) => {
        builder.addCase(getUser.pending, (state) => {
            state.status = 'loading'
            state.error = null
        })

        builder.addCase(getUser.fulfilled, (state, { payload }) => {
            state.status = 'idle'
            state.user = payload
        })

        builder.addCase(getUser.rejected, (state, { payload }) => {
            if (payload) state.error = payload
            state.status = 'failed'
        })
    },
})

export const getUserState = (state: { user: UserState }) => state.user
// export const { setName, setEmail } = userSlice.actions
export default userSlice.reducer

And here is the store.ts file

import { configureStore } from '@reduxjs/toolkit'
import userSlice from './slices/userSlice'
import {
    useDispatch as useDispatchBase,
    useSelector as useSelectorBase,
} from 'react-redux'

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

export type RootState = ReturnType<typeof store.getState>

type AppDispatch = typeof store.dispatch

export const useDispatch = () => useDispatchBase<AppDispatch>()

export const useSelector = <TSelected = unknown>(
    selector: (state: RootState) => TSelected
): TSelected => useSelectorBase<RootState, TSelected>(selector)

I followed the examples in this and this tutorial for setting up redux toolkit with typescript in NextJs.

Akshay Benny
  • 69
  • 1
  • 11

0 Answers0