1

I'm having trouble updating an object in my React / Redux reducer. The initial state is an object of Immutable. I'm stuck trying to update the object.

import Immutable from 'immutable';
import * as actionTypes from '../actions/actionTypes';

const initialState = Immutable.fromJS({
  user: {
    id: null,
    name: null,
    age: null
  }
});

export default function addUserReducer(state = initialState, action) {
  switch(action.type) {
    case actionTypes.ADD_USER:
      const user = {
        id: action.id,
        name: action.name,
        age: action.age
      }

      return state.setIn(['user'], user);
    default:
      return state;
  }
}

The state always returns a map with the values of id, name and age as null.

What's the correct way to update the state in my reducer?

2
  • 1
    Seems like action has not those properties. Did you try console.log(action) and see what is inside? The correct way probably should be set a user to the action and the do action.user Commented Jan 24, 2019 at 15:43
  • 1
    You code seems ok. Rather then you should not store plain objects inside immutable maps. You could use state.mergeDeep({user}) or state.setIn(['user'], fromJS(user)) Commented Jan 24, 2019 at 16:07

2 Answers 2

1

Use merge function in immutable to change the state.It can be implemented like this

import Immutable from 'immutable';
import * as actionTypes from '../actions/actionTypes';

const initialState = Immutable.fromJS({
  user: {
    id: null,
    name: null,
    age: null
  }
});

export default function addUserReducer(state = initialState, action) {
  switch(action.type) {
    case actionTypes.ADD_USER:
      // This will update the state in the reducer if you are using immutable library
      return state.merge({
        id: action.id,
        name: action.name,
        age: action.age
      });
    default:
      return state;
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Your code looks ok, and when I run it in a repl it works.

I tested it by adding the following:

const newState = addUserReducer(undefined, {
  type: 'ADD_USER', // I just assumed that's what your type resolves to.
  id: 1,
  name: 'FOO',
  age: 100,
});
console.log(newState); // Logs "Map { "user": [object Object] }"
console.log(Immutable.Map.isMap(newState); // true
console.log(Immutable.Map.isMap(newState.get('user'))) //false

I suspect the reason it's not working for you is because your action's actual type does not actually equal actionTypes.ADD_USER. I would double check that case in the reducer runs. A simple log in that case should tell you.

Also, like other comments have said above, right now your ADD_USER case is setting the user as a NON-Immutable object, so instead modify the ADD_USER return statement like so:

state.set('user', Immutable.Map(user));

Also note that since 'user' is a top-level key, Maps .set method works just fine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.