Skip to content

Commit 68b5061

Browse files
committed
naive react redux todo app
1 parent 8fa5a46 commit 68b5061

File tree

2 files changed

+135
-5
lines changed

2 files changed

+135
-5
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
},
88
"dependencies": {
99
"react": "^15.5.4",
10-
"react-dom": "^15.5.4"
10+
"react-dom": "^15.5.4",
11+
"redux": "^3.6.0"
1112
},
1213
"scripts": {
1314
"start": "react-scripts start",

src/index.js

Lines changed: 133 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,137 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
3-
import App from './App';
4-
import registerServiceWorker from './registerServiceWorker';
3+
import { combineReducers, createStore } from 'redux';
54
import './index.css';
65

7-
ReactDOM.render(<App />, document.getElementById('root'));
8-
registerServiceWorker();
6+
// action types
7+
8+
const TODO_ADD = 'TODO_ADD';
9+
const TODO_TOGGLE = 'TODO_TOGGLE';
10+
const FILTER_SET = 'FILTER_SET';
11+
12+
// reducers
13+
14+
const todos = [
15+
{ id: '0', name: 'learn redux' },
16+
{ id: '1', name: 'learn mobx' },
17+
];
18+
19+
function todoReducer(state = todos, action) {
20+
switch(action.type) {
21+
case TODO_ADD : {
22+
return applyAddTodo(state, action);
23+
}
24+
case TODO_TOGGLE : {
25+
return applyToggleTodo(state, action);
26+
}
27+
default : return state;
28+
}
29+
}
30+
31+
function applyAddTodo(state, action) {
32+
const todo = Object.assign({}, action.todo, { completed: false });
33+
return state.concat(todo);
34+
}
35+
36+
function applyToggleTodo(state, action) {
37+
return state.map(todo =>
38+
todo.id === action.todo.id
39+
? Object.assign({}, todo, { completed: !todo.completed })
40+
: todo
41+
);
42+
}
43+
44+
function filterReducer(state = 'SHOW_ALL', action) {
45+
switch(action.type) {
46+
case FILTER_SET : {
47+
return applySetFilter(state, action);
48+
}
49+
default : return state;
50+
}
51+
}
52+
53+
function applySetFilter(state, action) {
54+
return action.filter;
55+
}
56+
57+
// action creators
58+
59+
function doAddTodo(id, name) {
60+
return {
61+
type: TODO_ADD,
62+
todo: { id, name },
63+
};
64+
}
65+
66+
function doToggleTodo(id) {
67+
return {
68+
type: TODO_TOGGLE,
69+
todo: { id },
70+
};
71+
}
72+
73+
function doSetFilter(filter) {
74+
return {
75+
type: FILTER_SET,
76+
filter,
77+
};
78+
}
79+
80+
// store
81+
82+
const rootReducer = combineReducers({
83+
todoState: todoReducer,
84+
filterState: filterReducer,
85+
});
86+
87+
const store = createStore(rootReducer);
88+
89+
// components
90+
91+
function TodoApp({ todos, onToggleTodo }) {
92+
console.log(todos);
93+
return <TodoList
94+
todos={todos}
95+
onToggleTodo={onToggleTodo}
96+
/>;
97+
}
98+
99+
function TodoList({ todos, onToggleTodo }) {
100+
return (
101+
<div>
102+
{todos.map(todo => <TodoItem
103+
key={todo.id}
104+
todo={todo}
105+
onToggleTodo={onToggleTodo}
106+
/>)}
107+
</div>
108+
);
109+
}
110+
111+
function TodoItem({ todo, onToggleTodo }) {
112+
const { name, id, completed } = todo;
113+
return (
114+
<div>
115+
{name}
116+
<button
117+
type="button"
118+
onClick={() => onToggleTodo(id)}
119+
>
120+
{completed ? "Incomplete" : "Complete"}
121+
</button>
122+
</div>
123+
);
124+
}
125+
126+
function render() {
127+
ReactDOM.render(
128+
<TodoApp
129+
todos={store.getState().todoState}
130+
onToggleTodo={id => store.dispatch(doToggleTodo(id))}
131+
/>,
132+
document.getElementById('root')
133+
);
134+
}
135+
136+
store.subscribe(render);
137+
render();

0 commit comments

Comments
 (0)