The code is compiled by webpack but I have an error on the browser console.
The problem seems to be at the line : 'switch (action.type)'
Here is the code :
./reducer
import { produce } from 'immer';
import ActionTypeKeys from './actionTypeKeys';
import { AuthAction } from './actionTypes';
export type AuthState = {
isLoggedIn: boolean;
};
const initialState = { isLoggedIn: false };
export const authReducer = produce(
(action: AuthAction, draft: AuthState = initialState) => {
switch (action.type) {
case ActionTypeKeys.IS_LOGIN:
draft.isLoggedIn = action.payload;
break;
default:
throw new Error('No matching ActionTypeKeys was found!');
}
return draft;
}
);
./actionTypeKeys
enum ActionTypeKeys {
REFRESH_TOKEN = 'auth/REFRESH_TOKEN',
IS_LOGIN = 'auth/IS_LOGIN',
}
export default ActionTypeKeys;
The console error :
reducer.ts:14 Uncaught TypeError: Cannot read properties of undefined (reading 'type')
at reducer.ts:14:18
at immer.esm.js:1:16007
at e.produce (immer.esm.js:1:16373)
at immer.esm.js:1:15969
at redux.js:436:1
at Array.forEach (<anonymous>)
at assertReducerShape (redux.js:434:1)
at combineReducers (redux.js:499:1)
at Module../src/store/rootReducer.ts (rootReducer.ts:11:43)
at __webpack_require__ (bootstrap:24:1)
The error is triggering the line 'switch (action.type)'
I have no idea how to solve it.
Can someone bring me the light ?
CodePudding user response:
It seems that somewhere you are doing a dispatch(undefined)
, dispatch()
or dispatch(something())
where something
accidentally returns undefined
instead of an action object.
Apart from that:
Your throw new Error('No matching ActionTypeKeys was found!');
is a bug - in Redux, you always have to return state
when no matching action was found. As every action is always passed to every controller and the Redux-internal "INIT" action is randomized in dev, it is certain that every reducer will see at least one action that you do not know about.
Also, generally you are writing a very old style of Redux here. Modern Redux uses the official Redux Toolkit (which is the official recommendation since 2019) and does not use switch..case reducers, ACTION_TYPES, TypeScript action type unions and a lot of other things that have changed since. Especially with TypeScript you will probably save more than 3/4 of your code switching to the modern approach. We even explicitly recommend not to use action union types at this point. Please take a look at the Official Redux Essentials Tutorial as you might be following very outdated documentation.
CodePudding user response:
I updated my code for something like this:
import { createSlice } from '@reduxjs/toolkit';
import { User } from '../../common/interfaces/User';
export type AuthState = { user: User | null; isLogged: boolean };
const initialState: AuthState = { user: null, isLogged: false };
export const userSlice = createSlice({
name: 'auth',
initialState,
reducers: {
setUserAction: (state, action) => {
state.user = action.payload;
},
loginAction: (state, action) => {
state.isLogged = action.payload;
},
},
});
export const { setUserAction, loginAction } = userSlice.actions;
export default userSlice.reducer;
It is working perfecly !