【问题标题】:React/Redux/Immutable.js - Immutable actions (Error: Actions must be plain objects)React/Redux/Immutable.js - 不可变动作(错误:动作必须是普通对象)
【发布时间】:2017-10-23 13:25:41
【问题描述】:

我将 React 与 Redux 和 Immutable.js 一起使用 - 我的状态由不可变对象组成,并且工作正常。

现在我正在尝试使我的 actions 不可变对象而不是普通的 Javascript 对象。

我的 reducer 和 action creators 工作并且我所有的单元测试都通过了,但是当我尝试在 React 组件中使用不可变的 action 对象时,我得到了一个错误,因为我的 Action 对象是一个不可变的 Map(而不是一个普通的 javascript 对象) .

这是我的行动:

export const cancel = () => {
    return Immutable.Map({
        type: ACTION_TYPES.get('CANCEL')
    })
}

我的 reducer 是这样的(在单元测试时工作,但由于错误,React 从不调用它):

export const site = (state = initialState, action) => {
    const actionType = null
    try {
        action.get('type')
    } catch (e) {
        return state
    }
    switch (actionType) {
       ... so on and so forth ...

这是测试组件时的错误:

 FAIL  src/App.test.js
  ● Test suite failed to run

    Actions must be plain objects. Use custom middleware for async actions.

我需要添加什么中间件才能让我的 Immutable.js 对象作为操作工作?我在文档中找不到它...

【问题讨论】:

  • 您可能需要编写自己的中间件。我认为将动作作为不可变映射没有足够的好处,大多数开发工具和其他库都希望动作作为普通对象

标签: javascript reactjs react-redux immutable.js


【解决方案1】:

我需要添加什么中间件才能让我的 Immutable.js 对象作为操作工作?我在文档中找不到它...

如果您想构建自定义行为,您需要自己构建中间件。像这样的:

import { isImmutable } from 'immutable';

// Allows immutable objects to be passed in as actions. Unwraps them, then
// forwards them on to the reducer (or the next middleware).
const immutableMiddleware = store => next => action => {
    if (isImmutable(action)) {
        next(action.toJS())
    } else {
        next(action);
    }
};

也就是说,我并没有真正看到将操作作为不可变对象进行操作有什么好处。操作通常在需要时立即创建,并且永远不会再次访问,因此保护它免受突变几乎从来不是问题。而且您通常不会克隆它们,因此 immutablejs 在从旧对象创建新的不可变对象时提供的性能优势将无法实现。

【讨论】:

    猜你喜欢
    • 2017-05-09
    • 1970-01-01
    • 2019-04-26
    • 2020-06-13
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    相关资源
    最近更新 更多