简体   繁体   中英

ImmutableJS in Redux : Uncaught TypeError: oldArr.push is not a function

I have this reducer:

import Immutable, { Map, Record} from 'immutable'
const tags = Map({ primary: ['tag1','tag2','tag3'], secondary: [] });

export default function (state=tags, action) {
  switch (action.type) {
      case 'ADD_PRIMARY_TAG': {
        //not sure about this:
        var oldArr = state.get('primary');
        var newArr = oldArr.push(action.payload)
        var newState = tags.set('primary', newArr);
        return newState;
      }
      default:
        console.log("Default Tags Reducer.");
      return state;
    }
}

However, I am not sure about this. So i have an immutable Map and there I have an array called primary , which contains some tags. Now I would like to add a tag to the existing array. So I get the current array with state.get('primary'); , I push something into a copy of it, and then I set the new state to the new array and return it.

I don't see where I am going wrong, or whether I am using Immutable the wrong way maybe.

When i run this I get the following error:

Uncaught TypeError: oldArr.push is not a function at exports.default (index_bundle.js:44134) at combination (index_bundle.js:32954) at dispatch (index_bundle.js:18293) at index_bundle.js:44171 at Object.addPrimaryTag (index_bundle.js:32975) at PhraseView.tagsSubmit (index_bundle.js:33813) at Object.ReactErrorUtils.invokeGuardedCallback (index_bundle.js:6380) at executeDispatch (index_bundle.js:4920) at Object.executeDispatchesInOrder (index_bundle.js:4943) at executeDispatchesAndRelease (index_bundle.js:3439) at executeDispatchesAndReleaseTopLevel (index_bundle.js:3450)

Is the way I am using Arrays here (in the context of ImmutableJS) maybe completely wrong? Shoudl the Arrays in my Immutable Map be other immutable objects? Or how does this error come about?

You need to use concat() instead of push() .

The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.

Change:

var newArr = oldArr.push(action.payload);

To:

var newArr = oldArr.concat([action.payload]);

I just tried the following and it passes:

import Immutable, {Map} from 'immutable'

describe('immutable tests', () => {
  it('Immutable array', () => {
    const tags = Map({ primary: ['tag1','tag2','tag3'], secondary: [] });
    let oldArr = tags.get('primary');
    oldArr.push('blabla')
    expect(oldArr).toHaveLength(4)
  })
})

Are you sure the incoming state is what you expect it to be? Maybe it has some other structure, from the stacktrace it's not very clear what invokes your reducer

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