import { PayloadAction , createSlice } from "@reduxjs/toolkit" ; import { User , getUserData } from "../services/jsonPlaceholder" ; import { AppThunk , AppState } from "." ; interface UserDate { [ id ] : { readyStatus : string ; item ? : User ; error ? : string ; } ; } interface Success { id : string ; item : User ; } interface Failure { id : string ; error : string ; } const userData = createSlice ( { name : "userData" , initialState : { } as UserDate , reducers : { getRequesting : ( state , { payload } ) => { state [ payload ] = { readyStatus : "request" } ; } , getSuccess : ( state , { payload } ) => { state [ payload . id ] = { readyStatus : "success" , item : payload . item } ; } , getFailure : ( state , { payload } ) => { state [ payload . id ] = { readyStatus : "failure" , error : payload . error } ; } , } , } ) ; export default userData . reducer ; export const { getRequesting , getSuccess , getFailure } = userData . actions ; export const fetchUserData = ( id ) : AppThunk => async ( dispatch ) => { dispatch ( getRequesting ( id ) ) ; const { error , data } = await getUserData ( id ) ; if ( error ) { dispatch ( getFailure ( { id , error : error . message } ) ) ; } else { dispatch ( getSuccess ( { id , item : data as User } ) ) ; } } ; const shouldFetchUserData = ( state , id ) => state . userData [ id ] ?. readyStatus !== "success" ; export const fetchUserDataIfNeed = ( id ) : AppThunk => ( dispatch , getState ) => { if ( shouldFetchUserData ( getState ( ) , id ) ) return dispatch ( fetchUserData ( id ) ) ; return null ; } ;