TODO App wtih React (Reducer Composition using Objects)

TODO app using Redux and using object composition

by Pratik Bhattachary

HTML

<!DOCTYPE html>
<html>
  <meta name="description" content="TODO App using Redux">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>TODO Redux</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.0/redux.js" type="text/javascript"></script>
  <script src="https://fb.me/react-0.14.3.js"></script>
  <script src="https://fb.me/react-dom-0.14.3.js"></script>
  <script src="https://unpkg.com/expect@%3C21/umd/expect.min.js"></script>

  <body>
    <div id="root"></div>

  </body>

</html>

Babel + JSX

//Here state refers to an individual todo object
const todo = (state, action) => {
	switch(action.type) {
		case 'ADD_TODO': return {
			id: action.id,
			text: action.text,
			completed: false
		}
		case 'TOGGLE_TODO': 
			if (state.id === action.id)
				return Object.assign({}, state, { completed: !state.completed });
			return state;
		default: return state;
	}
};

const todos = (state = [], action) => {
	switch(action.type) {
		case 'ADD_TODO': 
			return [
				...state,
				todo(undefined, action)
			];
		case 'TOGGLE_TODO': {
			return state.map(t => todo(t, action));
		}
		default:
			return state;
	}
};

const visibilityFilter = (
	state = 'SHOW_ALL',
	action
) => {
	switch(action.type) {
		case 'SET_VISIBILITY_FILTER':
			return action.filter;
		default:
			return state;
	}
}

//This is the parent reducer which calls the child reducers. Each child reducer takes only 1 part of the state object and reduces it.
const todoApp = (state = {}, action) => {
	return {
		todos: todos(state.todos, action),
		visibilityFilter: visibilityFilter(state.visibilityFilter, action)
	};
};

const { createStore } = Redux;
const store = createStore(todoApp);

console.log('Initial state: ');
console.log(store.getState());
console.log('------------------');

console.log('Dispatching ADD_TODO');
store.dispatch({
	type: 'ADD_TODO',
	id: 0,
	text: 'Learn React'
});
console.log('Current State: ')
console.log(store.getState());
console.log('------------------');

console.log('Dispatching TOGGLE_TODO');
store.dispatch({
	type: 'TOGGLE_TODO',
	id: 0
});
console.log('Current State: ')
console.log(store.getState());
console.log('------------------');

console.log('Dispatching SET_VISIBILITY_FILTER');
store.dispatch({
	type: 'SET_VISIBILITY_FILTER',
	filter: 'SHOW_COMPLETED'
});
console.log('Current State: ')
console.log(store.getState());
console.log('------------------');


//Tests
const testAddTodo = () => {
	const stateBefore = [];
	const action = {
		type: 'ADD_TODO',
		id:...