简体   繁体   中英

React/Redux/Immutable.js - Immutable actions (Error: Actions must be plain objects)

I'm using React with Redux and Immutable.js - My state is composed of immutable objects and that works fine.

Now I'm trying to make my actions immutable objects instead of plain Javascript objects.

My reducers and action creators work and all my unit tests pass, but when I try to use the immutable action object in a React component I get an error because my Action object is an immutable Map (instead of a plain javascript object).

Here is my action:

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

My reducer is like this (works when unit tested but React never calls it due to the error):

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

Here is the error when testing a component:

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

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

What middleware do I need to add so that my Immutable.js objects work as actions? I cannot find it in the docs...

What middleware do I need to add so that my Immutable.js objects work as actions? I cannot find it in the docs...

If you want to build custom behavior, you'll need to build the middleware yourself. Something like this:

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);
    }
};

That said, i don't really see what benefit you get from doing actions as immutable objects. Actions are usually created right when they're needed, and never accessed again, so protecting it from mutation is almost never a concern. And you typically won't be cloning them, so the performance benefits that immutablejs provides when creating a new immutable object from an old one will be unrealized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM