I am new at Typescript and we are using hooks in our react application. We have a common thunk action creator which calls one of the actions.
appSlice.ts
type ThunkOptions = {
method: number,
api_url: string,
body: any | null
}
/**
* Thunk Action Creator Factory
* @param {String} name : Thunk Action Creator Name
* @returns Thunk Action Creator
*/
export const commonAsyncThunkCreator = (name: string) => {
return createAsyncThunk(name,async (options: ThunkOptions,{dispatch})=>{
let requestHelper;
if(options.method === REQUEST_METHOD.GET.id){
requestHelper = makeGetRequest;
}else if(options.method === REQUEST_METHOD.POST.id){
requestHelper = makePostRequest;
}
const response = await requestHelper(options.api_url,options.body);
if (response.status === 401) {
return dispatch(unauthorized());
}
if(response && response.result){ //TODO: to check
return response;
}
});
}
interface AppReducerInitialStateType {
isFetching: boolean,
isLoggedIn: boolean,
isSyncSuccess: boolean
}
let initialState : AppReducerInitialStateType = {
isFetching:false,
isLoggedIn:true,
isSyncSuccess: false
}
export const appReducer = createSlice({
name:"app",
initialState,
reducers:{
unauthorized:(state)=>{
state.isLoggedIn = false;
state.isSyncSuccess = false;
},
//other reducers
}
});
export const sync = commonAsyncThunkCreator('app/sync'); //a reducer function that i have not provided here but it sets isSyncSuccess flag
export default appReducer.reducer;
export const { unauthorized } = appReducer.actions;
commonAsyncThunkCreator
is used in my other reducers also.
In my component files when I access appReducer, it is not recognized. Note: Please ignore name of key accessed, I have omitted it here in my code snippet
Please tell me where I'm wrong or what approach should I take here
Update: I tried following steps of this post https://blog.logrocket.com/using-typescript-with-redux-toolkit/ but that didn't help either.
Also, I have found that if I do not export unauthorised
in appReducer.actions
, my appReducer gets recognized as a type but my code breaks since commonAsyncThunkCreator
can't work anymore
CodePudding user response:
Since my issue was being caused due to call to unauthorized reducer, I have removed its dependency completely.
export const commonAsyncThunkCreator = (name: string) => {
return createAsyncThunk(name,async (options: ThunkOptions,
{rejectWithValue})=>{
let requestHelper;
if(options.method === REQUEST_METHOD.GET.id){
requestHelper = makeGetRequest;
}else if(options.method === REQUEST_METHOD.POST.id){
requestHelper = makePostRequest;
}
const response = await requestHelper(options.api_url,options.body);
if (response.status === 401) {
return rejectWithValue('You are logged out');
}
if(response && response.result){
return response;
}
});
}
Next, I changed my extraReducers to builder syntax for TS handling and voila, my appReducer is now being recognized.
eg
builder.addCase(logout.pending,(state)=>{
state.isFetching = true;
}),
CodePudding user response:
I am not 100% sure @mk1024, but what about doing something like this :
in your appSlice file you can do
export const appSelector = (state: RootState) => state.app
and then
const { purchaseDetails } = useSelector(appSelector);
Here is some ressource that might be helpful as well https://blog.logrocket.com/using-typescript-with-redux-toolkit/
Here is an example :
https://github.com/Cvellle/Good-choice-app/blob/696baf99804611a3da27ed87b51f1770280214bd/client/src/app/store.ts ( make sure to add the correct typing in the rootstate )
https://github.com/Cvellle/Good-choice-app/blob/696baf99804611a3da27ed87b51f1770280214bd/client/src/features/login/loginSlice.ts How to create your slice and export it
How to import and use it https://github.com/Cvellle/Good-choice-app/blob/696baf99804611a3da27ed87b51f1770280214bd/client/src/features/header/Header.tsx#L22