In the previous section, we covered how to change state in the old way and how to do it in the new Redux-like way. The reducers are nothing more than pure functions; pure in the sense that they don't mutate but produce a new state. A reducer needs an action to work though. Let's deepen our knowledge on Reducers and Actions. Let's create an action meant to add things to a list and a reducer that goes with it:
// core-concepts/jedilist-reducer.js
let actionLuke = { type: "ADD_ITEM", payload: { name: "Luke" } };
let actionVader = { type: "ADD_ITEM", payload: "Vader" };
function jediListReducer(state = [], action) {
switch(action.type) {
case "ADD_ITEM":
return [... state, action.payload];
default:
return state;
}
}
let state = jediListReducer([], actionLuke);
console.log(state);
/*
[{ name: 'Luke '}]
*/
state = jediListReducer(state, actionVader);
console.log(state);
/*
[{ name: 'Luke' }, { name: 'Vader' }]
*/
module.exports = jediListReducer;
OK, so know we know how to deal with lists; what about objects? We again need to define an action and a reducer:
// core-concepts/selectjedi-reducer.js
let actionPerson = { type: "SELECT_JEDI", payload: { id: 1, name: "Luke" } };
let actionVader = { type: "SELECT_JEDI", payload: { id: 2, name: "Vader" } };
function selectJediReducer({}, action) {
switch (action.type) {
case "SELECT_JEDI":
return Object.assign({}, action.payload);
default:
return state;
}
}
state = selectJediReducer({}, actionPerson);
console.log(state);
/*
{ name: 'Luke' }
*/
state = selectJediReducer(state, actionVader);
console.log(state);
/*
{ name: 'Vader' }
*/
module.exports = selectJediReducer;
What we see here is how one object completely replaces the content of another object by invoking SELECT_JEDI. We also see how we use Object.assign() to ensure we only copy over the values from the incoming object.