Redux – Immutability

Methods for enforcing the key principle of state immutability in Redux. Immutable state means that we never modify the state directly, instead we return a new copy of the state.


const immutableTypesDefaultState = { lastInput: '', messages: ['message1', 'message2', 'message3'] };
const immutableTypesReducer = (state = immutableTypesDefaultState, action) => {
switch (action.type) {
case 'ADD_BAD': { /* BAD !!! PUSH IS STATE MUTATION */
// this.setState({ messages : this.state.messages.push(action.input)});
//console.log('looking to push ['+action.input+'] into messages array');
var newArray = state.messages;
newArray.push(action.input);
return { lastInput: action.input, messages: newArray };
}
case 'ADD_GOOD_NORMAL': { /* GOOD !!! THIS IS NOT MUTATION */
//console.log('looking to add ['+action.input+'] via concat');
var anotherArray = state.messages;
anotherArray = anotherArray.concat(action.input);
return { lastInput: action.input, messages: anotherArray };
}
case 'ADD_GOOD_SPREAD': { /* GOOD !!! THIS IS NOT MUTATION using the SPREAD operator */
//console.log('looking to add ['+action.input+'] via spread');
var yetAnotherArray = [...state.messages, action.input];
return { lastInput: action.input, messages: yetAnotherArray };
}
case 'REMOVE_ITEM': { /* GOOD !!! THIS IS NOT MUTATION using the SPREAD operator */
//console.log("requesting to remove an object on index:",action.input);
var slimmedArray = state.messages.filter(val => val != state.messages[action.input])
return { lastInput: action.input, messages: slimmedArray };
}
case 'OBJECT_ASSIGN': { /* GOOD !!! THIS IS OBJECT ASSIGNMENT WITHOUT MUTATION */
//console.log("requesting to change an object while enforcing state immutability with:",action.input);
var changeObject = Object.assign({}, immutableTypesDefaultState, { lastInput:action.input} );
return { lastInput: action.input, messages: changeObject };
}
default: return state;
}
}

const ImmutableTypesStore = createStore(immutableTypesReducer);
console.log(ImmutableTypesStore.getState());

setTimeout(function () {
ImmutableTypesStore.dispatch({ type: 'ADD_BAD', input: 'sample input for push' });
console.log(ImmutableTypesStore.getState());
}, 2000);

setTimeout(function () {
ImmutableTypesStore.dispatch({ type: 'ADD_GOOD_NORMAL', input: 'sample input for Good via concat' });
console.log(ImmutableTypesStore.getState());
}, 4000);

setTimeout(function () {
ImmutableTypesStore.dispatch({ type: 'ADD_GOOD_SPREAD', input: 'sample input for Good via spread' });
console.log(ImmutableTypesStore.getState());
}, 6000);

setTimeout(function () {
ImmutableTypesStore.dispatch({ type: 'REMOVE_ITEM', input: 1 });
console.log(ImmutableTypesStore.getState());
}, 8000);

setTimeout(function () {
ImmutableTypesStore.dispatch({ type: 'OBJECT_ASSIGN', input: 'Object.assigned was used for this' });
console.log(ImmutableTypesStore.getState());
}, 10000);

Advertisements