@@ -2,9 +2,14 @@ import React from 'react';
2
2
import ReactDOM from 'react-dom' ;
3
3
import { applyMiddleware , combineReducers , createStore } from 'redux' ;
4
4
import { Provider , connect } from 'react-redux' ;
5
- import { createLogger } from 'redux-logger'
5
+ import { createLogger } from 'redux-logger' ;
6
+ import { schema , normalize } from 'normalizr' ;
6
7
import './index.css' ;
7
8
9
+ // schemas
10
+
11
+ const todoSchema = new schema . Entity ( 'todo' ) ;
12
+
8
13
// action types
9
14
10
15
const TODO_ADD = 'TODO_ADD' ;
@@ -18,7 +23,14 @@ const todos = [
18
23
{ id : '1' , name : 'learn mobx' } ,
19
24
] ;
20
25
21
- function todoReducer ( state = todos , action ) {
26
+ const normalizedTodos = normalize ( todos , [ todoSchema ] ) ;
27
+
28
+ const initialTodoState = {
29
+ entities : normalizedTodos . entities . todo ,
30
+ ids : normalizedTodos . result ,
31
+ } ;
32
+
33
+ function todoReducer ( state = initialTodoState , action ) {
22
34
switch ( action . type ) {
23
35
case TODO_ADD : {
24
36
return applyAddTodo ( state , action ) ;
@@ -32,15 +44,17 @@ function todoReducer(state = todos, action) {
32
44
33
45
function applyAddTodo ( state , action ) {
34
46
const todo = { ...action . todo , completed : false } ;
35
- return [ ...state , todo ] ;
47
+ const entities = { ...state . entities , [ todo . id ] : todo } ;
48
+ const ids = [ ...state . ids , action . todo . id ] ;
49
+ return { ...state , entities, ids } ;
36
50
}
37
51
38
52
function applyToggleTodo ( state , action ) {
39
- return state . map ( todo =>
40
- todo . id === action . todo . id
41
- ? { ...todo , completed : ! todo . completed }
42
- : todo
43
- ) ;
53
+ const id = action . todo . id ;
54
+ const todo = state . entities [ id ] ;
55
+ const toggledTodo = { ...todo , completed : ! todo . completed } ;
56
+ const entities = { ... state . entities , [ id ] : toggledTodo } ;
57
+ return { ... state , entities } ;
44
58
}
45
59
46
60
function filterReducer ( state = 'SHOW_ALL' , action ) {
@@ -100,12 +114,12 @@ function TodoApp() {
100
114
return < ConnectedTodoList /> ;
101
115
}
102
116
103
- function TodoList ( { todos } ) {
117
+ function TodoList ( { todosAsIds } ) {
104
118
return (
105
119
< div >
106
- { todos . map ( todo => < ConnectedTodoItem
107
- key = { todo . id }
108
- todo = { todo }
120
+ { todosAsIds . map ( todoId => < ConnectedTodoItem
121
+ key = { todoId }
122
+ todoId = { todoId }
109
123
/> ) }
110
124
</ div >
111
125
) ;
@@ -128,20 +142,26 @@ function TodoItem({ todo, onToggleTodo }) {
128
142
129
143
// Connecting React and Redux
130
144
131
- function mapStateToProps ( state ) {
145
+ function mapStateToPropsList ( state ) {
146
+ return {
147
+ todosAsIds : state . todoState . ids ,
148
+ } ;
149
+ }
150
+
151
+ function mapStateToPropsItem ( state , props ) {
132
152
return {
133
- todos : state . todoState ,
153
+ todo : state . todoState . entities [ props . todoId ] ,
134
154
} ;
135
155
}
136
156
137
- function mapDispatchToProps ( dispatch ) {
157
+ function mapDispatchToPropsItem ( dispatch ) {
138
158
return {
139
159
onToggleTodo : id => dispatch ( doToggleTodo ( id ) ) ,
140
160
} ;
141
161
}
142
162
143
- const ConnectedTodoList = connect ( mapStateToProps ) ( TodoList ) ;
144
- const ConnectedTodoItem = connect ( null , mapDispatchToProps ) ( TodoItem ) ;
163
+ const ConnectedTodoList = connect ( mapStateToPropsList ) ( TodoList ) ;
164
+ const ConnectedTodoItem = connect ( mapStateToPropsItem , mapDispatchToPropsItem ) ( TodoItem ) ;
145
165
146
166
ReactDOM . render (
147
167
< Provider store = { store } >
0 commit comments