Home > front end >  Redux switch case error on reducer ts file
Redux switch case error on reducer ts file

Time:02-01

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 !

  •  Tags:  
  • Related