0

In React we have a best practice not modify state directly i.e. mutation... It is also important in Redux...

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

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

The above doesn't work, but can anyone help me how to properly update that nested objects property?

Antonio Pavicevac-Ortiz
  • 7,239
  • 17
  • 68
  • 141

2 Answers2

1

You can do this

return {...state, users:{...state.users, isLoggedIn : true}}
Antonio Pavicevac-Ortiz
  • 7,239
  • 17
  • 68
  • 141
kooskoos
  • 4,622
  • 1
  • 12
  • 29
1

Looks like you're both mutating state and returning a new state object. You're mutating state by saying state.users.isLoggedIn = .., but then returning a new state object by doing return Object.assign(...).

Instead maybe just do

case actionTypes.users.IS_LOGGED_OUT:
  return { ...state, users: { ...state.users, isLoggedIn: false }};

An alternative would be to create a copy of state and modify it instead

// Create new object so we don't mutate state
let newState = {...state, users: {...state.users}; 
// Remember to do this for each nested object or you 
// will still be referencing that piece of the original state
switch (action.type) {
  case actionTypes.users.IS_LOGGED_IN:
    newState.users.isLoggedIn = true; // Make your changes
    return newState; // Return new state
  case actionTypes.users.IS_LOGGED_OUT:
    newState.users.isLoggedIn = true;
    return newState;
  default:
    return state;
}
Brian Thompson
  • 13,263
  • 4
  • 23
  • 43
  • 2
    I forgot to spread state.users, saw your answer and remembered. Thanks – kooskoos Dec 19 '19 at 17:53
  • Thanks Brian, but this `case actionTypes.users.IS_LOGGED_IN: return {...state, users: {...state.users, isLoggedIn: true } };` yields `{users: isLoggedIn: false users: {isLoggedIn: true}}` – Antonio Pavicevac-Ortiz Dec 19 '19 at 18:23
  • That return value doesn't look like a valid format? is that exactly what its returning? Or is it supposed to be `{isLoggedIn: false}, `? – Brian Thompson Dec 19 '19 at 18:54