Skip to content

Commit 583015b

Browse files
committed
normalized state
1 parent 7f3c60a commit 583015b

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"react-scripts": "1.0.7"
77
},
88
"dependencies": {
9+
"normalizr": "^3.2.3",
910
"react": "^15.5.4",
1011
"react-dom": "^15.5.4",
1112
"react-redux": "^5.0.5",

src/index.js

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ import React from 'react';
22
import ReactDOM from 'react-dom';
33
import { applyMiddleware, combineReducers, createStore } from 'redux';
44
import { Provider, connect } from 'react-redux';
5-
import { createLogger } from 'redux-logger'
5+
import { createLogger } from 'redux-logger';
6+
import { schema, normalize } from 'normalizr';
67
import './index.css';
78

9+
// schemas
10+
11+
const todoSchema = new schema.Entity('todo');
12+
813
// action types
914

1015
const 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

3345
function 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

3852
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 };
4458
}
4559

4660
function 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

146166
ReactDOM.render(
147167
<Provider store={store}>

0 commit comments

Comments
 (0)