Redux: Never Mutate State
Tags: react, javascript, devops, beginners
Published: 2021-12-01 17:20:50

* Today FreeCodeCamp will be giving us a lesson about enforcing the key [principle of state immutability in Redux. Which means that you never modify state directly. Instead you return a new copy of state.
* Redux does not actively enforce state immutability in its store or reducers. Remember strings and numbers are primitive values and are immutable by nature. In other words, 3 is always 3. You cannot change the value of the number 3. An array or object, however, is mutable.
* Code:
```React
const ADD_TO_DO = 'ADD_TO_DO';

// A list of strings representing tasks to do:
const todos = [
  'Go to the store',
  'Clean the house',
  'Cook dinner',
  'Learn to code',
];

const immutableReducer = (state = todos, action) => {
  switch(action.type) {
    case ADD_TO_DO:
      // Don't mutate state here or the tests will fail
      return
    default:
      return state;
  }
};

const addToDo = (todo) => {
  return {
    type: ADD_TO_DO,
    todo
  }
}

const store = Redux.createStore(immutableReducer);
```
* Above we have a `store` and `reducer` in the code editor for managing to-do items. You have to finish writing the `ADD_TO_DO` case in the reducer to append a new-to-do to the state. You have tp find a way to return a new array with the item from action.todo appended to the end.

* Answer:
```React
const ADD_TO_DO = 'ADD_TO_DO';

const todos = [
  'Go to the store',
  'Clean the house',
  'Cook dinner',
  'Learn to code',
];

const immutableReducer = (state = todos, action) => {
  switch(action.type) {
    case ADD_TO_DO:
      let newList = [...todos]
      newList.push(action.todo)
      return newList;
    default:
      return state;
  }
};

const addToDo = (todo) => {
  return {
    type: ADD_TO_DO,
    todo
  }
}

const store = Redux.createStore(immutableReducer);

store.dispatch(addToDo('PS5 Time'))****
console.log(store.getState()) // 
[ 'Go to the store',
  'Clean the house',
  'Cook dinner',
  'Learn to code',
  'PS5 Time' ]


console.log(todos) // 
[ 'Go to the store',
  'Clean the house',
  'Cook dinner',
  'Learn to code' ]
```

### Use the Spread Operator on Arrays
* (ES6) To help enforce state immutability in Redux is the spread operator: `....` which I used in the lesson above which produces a new array from an existing array. 
* To clone an array but add additional values in the new array, you could write `[...myArray, 'new value']`. This would return a new array composed of the values in myArray and the string new value as the last value.
* It's important to know that it only makes a shallow copy of the array. It only provides immutable array operations for one-dimensional arrays.

* Code:
```React
const immutableReducer = (state = ['Do not mutate state!'], action) => {
  switch(action.type) {
    case 'ADD_TO_DO':
      // Don't mutate state here or the tests will fail
      return
    default:
      return state;
  }
};

const addToDo = (todo) => {
  return {
    type: 'ADD_TO_DO',
    todo
  }
}

const store = Redux.createStore(immutableReducer);
```

* Answer:
```React
const immutableReducer = (state = ['Do not mutate state!'], action) => {
  switch(action.type) {
    case 'ADD_TO_DO':
      let newArray = [...state, action.todo]
      return newArray
    default:
      return state;
  }
};
```

### Remove an Item from an Array

* Now we gotta practice removing items from an array. Other useful JavaScript methods include `slice()` and `concat()`.

* The reducer and action creator were modified to remove an item from an array based on the index of the item. Let's Finish writing the reducer so a new state array is returned with the item at the specific index removed.

*Code:
```React
const immutableReducer = (state = [0,1,2,3,4,5], action) => {
  switch(action.type) {
    case 'REMOVE_ITEM':
      // Don't mutate state here or the tests will fail
      return
    default:
      return state;
  }
};

const removeItem = (index) => {
  return {
    type: 'REMOVE_ITEM',
    index
  }
}

const store = Redux.createStore(immutableReducer);
```

* Answer:
```React
const immutableReducer = (state = [0,1,2,3,4,5], action) => {
  switch(action.type) {
    case 'REMOVE_ITEM':
      let a = state.slice(0, action.index)
      let b = state.slice(action.index + 1)
      return a.concat(b)
    default:
      return state;
  }
};

const removeItem = (index) => {
  return {
    type: 'REMOVE_ITEM',
    index
  }
}

const store = Redux.createStore(immutableReducer);
```

Larson, Q., 2019. Frontend Development Libraries. [online] Freecodecamp.org. Available at: https://www.freecodecamp.org/learn/front-end-development-libraries/redux