【问题标题】:Redux: Uncaught Error: Actions may not have an undefined "type" property. Have you misspelled a constant?Redux:未捕获的错误:操作可能没有未定义的“类型”属性。你有没有拼错一个常数?
【发布时间】:2019-12-18 15:38:01
【问题描述】:

我决定拆分我的 redux 存储——现在代表逻辑存储桶,即users, ui 等。

这些是每个包含每个类别的初始状态、动作类型和减速器的文件:

ui reducer 文件

/*./reducers/ui/index' reducer for ui */

/* initial state */
export const uiStartState = { ui: { modalActive: false } }

/* action types */
export const actionTypes = {
    ui: { MODAL_ACTIVE: 'MODAL_ACTIVE' },
    ui: { MODAL_INACTIVE: 'MODAL_INACTIVE' },
}

/* reducer(s) */
export default function ui(state = uiStartState, action) {
    switch (action.type) {
        case actionTypes.MODAL_ACTIVE:
            return Object.assign({}, state, { ui: { modalActive: true } });
        case actionTypes.MODAL_INACTIVE:
            return Object.assign({}, state, { ui: { modalActive: false } });

        default:
            return state
    }
};

/* actions */
export const modalStateOn = () => {
    return { type: actionTypes.ui.MODAL_ACTIVE }
}
export const modalStateOff = () => {
    return { type: actionTypes.ui.MODAL_INACTIVE }
}

用户减速器文件

/*./reducers/users/index' reducer for ui */

/* initial state */
export const usersStartState = { users: { isLoggedIn: false } }

/* action types */
export const actionTypes = {
    users: { IS_LOGGED_IN: 'IS_LOGGED_IN' },
    users: { IS_LOGGED_OUT: 'IS_LOGGED_OUT' },
}

/* reducer(s) */
export default function users(state = usersStartState, action) {
    switch (action.type) {
        case actionTypes.users.IS_LOGGED_IN:
            return Object.assign({}, state, {
                users: { isLoggedIn: true }
            });
        case actionTypes.users.IS_LOGGED_OUT:
            return Object.assign({}, state, {
                users: { isLoggedIn: false }
            });
        default:
            return state
    }
};

/* actions */
export const logInUser = () => {
    return { type: actionTypes.users.IS_LOGGED_IN }
}
export const logOutUser = () => {
    return { type: actionTypes.users.IS_LOGGED_OUT }
}

这是我的商店:

import { applyMiddleware, combineReducers, createStore } from 'redux'

/* imported reducers */
import ui from './reducers/ui/index'
import users from './reducers/users/index'

import { composeWithDevTools } from 'redux-devtools-extension'
import { persistStore } from 'redux-persist';

import { createLogger } from 'redux-logger'
import thunkMiddleware from 'redux-thunk'

var rootReducer = combineReducers({
    ui,
    users
})

export default () => {
    let store;
    const isClient = typeof window !== 'undefined';
    if (isClient) {
        const { persistReducer } = require('redux-persist');
        const storage = require('redux-persist/lib/storage').default;
        const persistConfig = {
            key: 'primary',
            storage,
            whitelist: ['isLoggedIn', 'modalActive'], // place to select which state you want to persist

        }
        store = createStore(
            persistReducer(persistConfig, rootReducer), {
                ui: { modalActive: false },
                users: { isLoggedIn: false }
            },
            composeWithDevTools(applyMiddleware(
                thunkMiddleware,
                createLogger({ collapsed: false })
            ))
        );
        store.__PERSISTOR = persistStore(store);
    } else {
        store = createStore(
            rootReducer, {
                ui: { modalActive: false },
                users: { isLoggedIn: false }
            },
            composeWithDevTools(applyMiddleware(
                thunkMiddleware,
                createLogger({ collapsed: false })
            ))
        );
    }
    return store;
};

所以把我的actionsusers 拿走:

export const logInUser = () => {
    return { type: actionTypes.users.IS_LOGGED_IN }
}
export const logOutUser = () => {
    return { type: actionTypes.users.IS_LOGGED_OUT }
}

不知道为什么错误说我没有名称为typekey,我认为这是重组的问题。

提前致谢!

更新

我想知道是不是我错误地合并了新状态?

来自我的减速器:

case actionTypes.users.IS_LOGGED_IN:
  return Object.assign({}, state, {
         users: { isLoggedIn: true }
         });

我对 redux 工具的状态反馈:

您可以看到next stateusers 对象得到另一个users 对象嵌套在具有正确有效负载的原始对象中!

【问题讨论】:

    标签: redux react-redux redux-persist redux-actions redux-store


    【解决方案1】:

    您的用户操作类型必须采用以下格式:

    export const actionTypes = {
      users: { IS_LOGGED_IN: "IS_LOGGED_IN", IS_LOGGED_OUT: "IS_LOGGED_OUT" }
    };
    

    使用您的代码,actionTypes.users.IS_LOGGED_IN 将是 undefined,因为您在同一个对象中有相同的键,它将被替换。这就是 redux 抱怨的原因。

    另外 ui 动作类型必须是:

    export const actionTypes = {
      ui: { MODAL_ACTIVE: "MODAL_ACTIVE", MODAL_INACTIVE: "MODAL_INACTIVE" }
    };
    

    也许您可以将所有操作类型保存在一个对象中,如下所示:

    export const actionTypes = {
      users: { IS_LOGGED_IN: "IS_LOGGED_IN", IS_LOGGED_OUT: "IS_LOGGED_OUT" },
      ui: { MODAL_ACTIVE: "MODAL_ACTIVE", MODAL_INACTIVE: "MODAL_INACTIVE" }
    };
    

    更新:关于您的问题合并状态:

    你可以这样试试吗?

    export default function users(state = usersStartState, action) {
      switch (action.type) {
        case actionTypes.users.IS_LOGGED_IN:
          return {
            ...state,
            users: {
              ...state.users,
              isLoggedIn: true
            }
          };
        case actionTypes.users.IS_LOGGED_OUT:
          return {
            ...state,
            users: {
              ...state.users,
              isLoggedIn: false
            }
          };
        default:
          return state;
      }
    }
    

    【讨论】:

    • 感谢您的帮助!就像我上面提到的,也许我错误地合并了新状态?
    • @AntonioPavicevac-Ortiz 你不应该用你的问题更新我的答案:) 我需要检查你的新问题,但我认为我们在你原来的问题中解决了这个问题。
    • @AntonioPavicevac-Ortiz 我更新了这个问题,试一试。你可以检查吗?但无论如何,即使存在状态问题,我认为这个答案也可以被接受为答案,因为它解决了你的问题。混合问题不好。
    • @AntonioPavicevac-Ortiz 你能把这个答案当作答案吗?
    • 对不起。接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 2021-05-22
    相关资源
    最近更新 更多