@@ -4,20 +4,51 @@ import { addTodo, completeTodo, setVisibilityFilter, changeTheme, VisibilityFilt
4
4
import AddTodo from '../components/AddTodo'
5
5
import TodoList from '../components/TodoList'
6
6
import Footer from '../components/Footer'
7
+ import { memoize , createMemoizedFunction } from '../memoize'
8
+
9
+ function selectTodos ( todos , filter ) {
10
+ console . log ( "Recalculating selectTodos" ) ;
11
+ switch ( filter ) {
12
+ case VisibilityFilters . SHOW_ALL :
13
+ return todos
14
+ case VisibilityFilters . SHOW_COMPLETED :
15
+ return todos . filter ( todo => todo . completed )
16
+ case VisibilityFilters . SHOW_ACTIVE :
17
+ return todos . filter ( todo => ! todo . completed )
18
+ }
19
+ }
20
+
21
+ function selectMatchingTodos ( todos , search ) {
22
+ console . log ( "Recalculating matchingTodos" ) ;
23
+ return todos . filter ( ( todo ) => { return todo . text . search ( search ) >= 0 ; } ) ;
24
+ }
7
25
8
26
class App extends Component {
27
+ constructor ( props , context ) {
28
+ super ( props , context ) ;
29
+ this . state = { search : '' } ;
30
+ }
31
+
32
+ visibleTodos = createMemoizedFunction ( ( ) => [ this . props . todos , this . props . visibilityFilter ] , selectTodos ) ;
33
+ matchingTodos = createMemoizedFunction ( ( ) => [ this . visibleTodos ( ) , this . state . search ] , selectMatchingTodos ) ;
34
+
35
+ updateSearch = function ( e ) {
36
+ this . setState ( { search : e . target . value } ) ;
37
+ }
38
+
9
39
render ( ) {
10
40
console . log ( this . props ) ;
11
41
// Injected by connect() call:
12
- const { dispatch, visibleTodos , visibilityFilter, currentTheme } = this . props
42
+ const { dispatch, visibilityFilter, currentTheme } = this . props
13
43
return (
14
44
< div className = { currentTheme } >
45
+ Search: < input type = "text" onChange = { this . updateSearch . bind ( this ) } /> < br />
15
46
< AddTodo
16
47
onAddClick = { text =>
17
48
dispatch ( addTodo ( text ) )
18
49
} />
19
50
< TodoList
20
- todos = { visibleTodos }
51
+ todos = { this . matchingTodos ( ) }
21
52
onTodoClick = { index =>
22
53
dispatch ( completeTodo ( index ) )
23
54
} />
@@ -33,7 +64,7 @@ class App extends Component {
33
64
}
34
65
35
66
App . propTypes = {
36
- visibleTodos : PropTypes . arrayOf ( PropTypes . shape ( {
67
+ todos : PropTypes . arrayOf ( PropTypes . shape ( {
37
68
text : PropTypes . string . isRequired ,
38
69
completed : PropTypes . bool . isRequired
39
70
} ) ) ,
@@ -44,22 +75,11 @@ App.propTypes = {
44
75
] ) . isRequired
45
76
}
46
77
47
- function selectTodos ( todos , filter ) {
48
- switch ( filter ) {
49
- case VisibilityFilters . SHOW_ALL :
50
- return todos
51
- case VisibilityFilters . SHOW_COMPLETED :
52
- return todos . filter ( todo => todo . completed )
53
- case VisibilityFilters . SHOW_ACTIVE :
54
- return todos . filter ( todo => ! todo . completed )
55
- }
56
- }
57
-
58
78
// Which props do we want to inject, given the global state?
59
79
// Note: use https://github.com/faassen/reselect for better performance.
60
80
function select ( state ) {
61
81
return {
62
- visibleTodos : selectTodos ( state . todos , state . visibilityFilter ) ,
82
+ todos : state . todos ,
63
83
visibilityFilter : state . visibilityFilter ,
64
84
currentTheme : state . currentTheme
65
85
}
0 commit comments