I am making an Axios call to get data. What should be the type for Axios call? For now, the type is any but how can I make it more strict?
import axios from "axios";
import { createContext, useEffect, useContext, useReducer } from "react";
import { Action, LevelsType, State, StateContextType, StateProviderPropsType } from "../Types/types";
const LevelCtx = createContext({} as StateContextType);
export function LevelProvider({children}:StateProviderPropsType) {
const initialState:State = {
levels: null
}
const [state, dispatch] = useReducer(reducer, initialState)
useEffect(() => {
(async () => {
const response = await axios.get<any>("http://localhost:5000/levels"); // Fix required.
return dispatch({type: "SET_LEVELS", payload: response.data.levels})
})();
}, [])
function reducer(state:State, action: Action) {
switch (action.type) {
case "SET_LEVELS":
return {...state, levels: action.payload }
default:
return state
}
}
console.log("levelCTX", state);
return (
<LevelCtx.Provider value={{ state, dispatch }}>
{children}
</LevelCtx.Provider>
)
};
export function useLevelCtx() {
return useContext(LevelCtx);
}
My types file looks like this -
import { ReactNode }from "react";
export type LevelsObjectType = {
_id: string;
img: string;
levelName: string;
__v: number;
}
export type LevelsType = {
levels: LevelsObjectType[]
}
export type State = {
levels: LevelsType[] | null;
}
export type StateProviderPropsType = {
children: ReactNode;
}
export type StateContextType = {
state: State;
dispatch: React.Dispatch<Action>;
}
export type Action =
| { type: "SET_LEVELS"; payload: LevelsType[] }
export type ServerError = {
errorMessage: string;
}
The data I am getting from the api call is this -
Now after doing this when i try to map over state.levels, it throw the following error -
I tried adding LevelsType to the above axios call but it is throwing an error. I am trying to setup useRecuder and useContext using React TS. I am new to typescript. So please help me figure out this.
CodePudding user response:
You could have two types:
export type LevelsObjectType = {
_id: string;
img: string;
levelName: string;
__v: number;
}
export type LevelsObjectTypeResult = {
levelsObjects: LevelsObjectType[],
success: boolean
}
And return:
await axios.get<LevelsObjectTypeResult>("http://localhost:5000/levels")
In the reducer:
return {...state, levels: action.payload.levelsObjects }
CodePudding user response:
You are getting an error because of the way your State
type is defined
export type State = {
levels: LevelsType[] | null;
}
When you do state.levels.map(level)
, level type is LevelsType
which you defined like this
export type LevelsType = {
levels: LevelsObjectType[]
}
so you are trying to access _id
on a LevelsType
object and obviously typescript complains about it since _id
doesn't exist in LevelsType
.
Try this:
export type State = {
levels: LevelsObjectType[] | null;
}