Reducers
Let's imagine we're building a simple counter program, that increments and decrements by one when the user signals the respective intention. In most Redux tutorials and literature you will see, such a reducer would ordinarily look a lot like this:
export default function counterReducer(state = 0, action) {
switch (action.type) {
case "INCREMENT": return state+1,
case "DECREMENT": return state-1,
default: return state
}
}
With the FSA-compliant action creators we discussed in the previous section, we get some nicer tools to alleviate the switch-statement boilerplate. Let's start by creating some actions:
// actions/counter.js
export const increment = createAction("increment");
export const decrement = createAction("decrement");
// or alternatively,
import actionMirror from "vishnu/utils/action-mirror";
export default actionMirror(['increment', 'decrement']);
import { increment, decrement } from 'actions/counter.js';
const reducer = handleActions({
[increment]: state => ({ counter: state.counter + action.payload }),
[decrement]: state => ({ counter: state.counter - action.payload })
}, { counter: 0 });
Obviously, this is a super contrived example, but from our container component, we could trigger these actions with the following:
import { increment, decrement } from 'actions/counter.js';
const stateMap = state => ({ counter: state.counter })
const actionMap = dispatch => ({
increment: () => dispatch(increment),
decrement: () => dispatch(decrement)
})
export default connect(stateMap, actionMap)(Ember.Component.extend({
layout: hbs`
Counter is: {{ counter }}
<button>{{ action "increment" }} +</button>
<button>{{ action "decrement" }} -</button>
`,
}))