@@ -2,9 +2,14 @@ import React from 'react';
22import ReactDOM from 'react-dom' ;
33import { applyMiddleware , combineReducers , createStore } from 'redux' ;
44import { Provider , connect } from 'react-redux' ;
5- import { createLogger } from 'redux-logger'
5+ import { createLogger } from 'redux-logger' ;
6+ import { schema , normalize } from 'normalizr' ;
67import './index.css' ;
78
9+ // schemas
10+
11+ const todoSchema = new schema . Entity ( 'todo' ) ;
12+
813// action types
914
1015const TODO_ADD = 'TODO_ADD' ;
@@ -18,7 +23,14 @@ const todos = [
1823 { id : '1' , name : 'learn mobx' } ,
1924] ;
2025
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 ) {
2234 switch ( action . type ) {
2335 case TODO_ADD : {
2436 return applyAddTodo ( state , action ) ;
@@ -32,15 +44,17 @@ function todoReducer(state = todos, action) {
3244
3345function applyAddTodo ( state , action ) {
3446 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 } ;
3650}
3751
3852function 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 } ;
4458}
4559
4660function filterReducer ( state = 'SHOW_ALL' , action ) {
@@ -100,12 +114,12 @@ function TodoApp() {
100114 return < ConnectedTodoList /> ;
101115}
102116
103- function TodoList ( { todos } ) {
117+ function TodoList ( { todosAsIds } ) {
104118 return (
105119 < div >
106- { todos . map ( todo => < ConnectedTodoItem
107- key = { todo . id }
108- todo = { todo }
120+ { todosAsIds . map ( todoId => < ConnectedTodoItem
121+ key = { todoId }
122+ todoId = { todoId }
109123 /> ) }
110124 </ div >
111125 ) ;
@@ -128,20 +142,26 @@ function TodoItem({ todo, onToggleTodo }) {
128142
129143// Connecting React and Redux
130144
131- function mapStateToProps ( state ) {
145+ function mapStateToPropsList ( state ) {
146+ return {
147+ todosAsIds : state . todoState . ids ,
148+ } ;
149+ }
150+
151+ function mapStateToPropsItem ( state , props ) {
132152 return {
133- todos : state . todoState ,
153+ todo : state . todoState . entities [ props . todoId ] ,
134154 } ;
135155}
136156
137- function mapDispatchToProps ( dispatch ) {
157+ function mapDispatchToPropsItem ( dispatch ) {
138158 return {
139159 onToggleTodo : id => dispatch ( doToggleTodo ( id ) ) ,
140160 } ;
141161}
142162
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 ) ;
145165
146166ReactDOM . render (
147167 < Provider store = { store } >
0 commit comments