I am trying to setup my Redux store with React and TypeScript but it gives me an error that my auth reducer is undefined.
This is my store.ts:
import {Action, applyMiddleware, combineReducers, compose, createStore} from 'redux';
import { auth, IAuthState } from './Auth/reducer';
import { general, IGeneralState } from './General/reducer';
export interface IAppState {
auth: IAuthState;
general: IGeneralState;
}
export const rootReducer = () => combineReducers({
auth: auth,
general: general,
});
const store = createStore<IAppState, Action<any>, {}, {}>(
rootReducer(),
(window as any).__REDUX_DEVTOOLS_EXTENSION__ &&
(window as any).__REDUX_DEVTOOLS_EXTENSION__()
);
export { store };
This is my auth reducer:
import { User } from '../../interfaces/user.interface';
import { AuthActionTypes } from './actions';
export interface IAuthState {
user: User;
authenticated: boolean;
}
const initialState: IAuthState = {
user: null,
authenticated: true,
};
export const auth = (state: IAuthState = initialState, action: any): IAuthState => {
switch (action.type) {
case AuthActionTypes.Setuser:
const { User } = action.payload;
return {
...state,
user: User
};
case AuthActionTypes.Logout:
return {
...state,
user: null,
authenticated: false,
};
}
};
It gives me the error:
Uncaught Error: Reducer "auth" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined.
Only thing what you need to do is always return a value from the reducer, even if it is null.
The following fix will do the job:
export const auth = (state: IAuthState = initialState, action: any): IAuthState => {
switch (action.type) {
case AuthActionTypes.Setuser:
const { User } = action.payload;
return {
...state,
user: User
};
case AuthActionTypes.Logout:
return {
...state,
user: null,
authenticated: false,
};
}
// this step was missing
return state;
};
Few rules what you need to follow:
null.undefined.{...state, newValue: false}.From documentation:
We return the previous state in the default case. It's important to return the previous state for any unknown action.
Read further: Handling Actions
I hope this helps!
Reducer is a simple function that returns state no matter if it has changed or not. You are missing the default case in your reducer so just replace it with below :
export const auth = (state: IAuthState = initialState, action: any): IAuthState => {
switch (action.type) {
case AuthActionTypes.Setuser:
const { User } = action.payload;
return {
...state,
user: User
};
case AuthActionTypes.Logout:
return {
...state,
user: null,
authenticated: false,
};
default: // this are 2 lines ive added
return state
}
};
Hope it helps. feel free for doubts
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With