代码是由webpack编译的,但我在浏览器控制台上遇到了一个错误。
问题似乎出在这一行:"开关(动作类型(">
这是代码:
/减速器
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;
控制台错误:
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)
错误触发线路"开关(动作类型(">
我不知道该怎么解决。
有人能把灯给我吗?
似乎在执行dispatch(undefined)
、dispatch()
或dispatch(something())
时,something
意外返回undefined
而不是操作对象。
除此之外:您的throw new Error('No matching ActionTypeKeys was found!');
是一个错误-在Redux中,当没有找到匹配的操作时,您总是必须使用return state
。由于每个动作总是传递给每个控制器;INIT";操作在dev中是随机的,可以肯定的是,每个reducer都会看到至少一个您不知道的操作。
此外,一般来说,你在这里写的是一种非常古老的Redux风格。Modern Redux使用官方的Redux工具包(这是自2019年以来的官方建议(,不使用switch。。case reducers、ACTION_TYPES、TypeScript操作类型联合以及此后发生的许多其他变化。尤其是使用TypeScript,您可能会节省3/4以上的代码,转而使用现代方法。在这一点上,我们甚至明确建议而不是使用操作联合类型。请查看官方Redux Essentials教程,因为您可能正在使用非常过时的文档。
我更新了类似以下内容的代码:
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;
它运行得很好!
我认为,用produce
创建减速器是不正确的。
initialState
作为单独的produce
arg传递- 无需从回调中返回草稿
- reducer回调中没有默认参数值
- 在意外的操作类型上抛出错误是一种糟糕的做法
尝试以下操作:
import { produce } from 'immer';
// ...
const authReducer = produce((draft: AuthState, action: AuthAction) => {
switch (action?.type) {
case ActionTypeKeys.IS_LOGIN:
draft.isLoggedIn = action.payload;
break;
}
}, initialState);
请参见示例。