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:...