1
- import PropTypes from 'prop-types'
2
1
import _ from 'lodash'
3
2
import faker from 'faker'
4
- import React , { Component } from 'react'
3
+ import React from 'react'
5
4
import { Search , Grid , Header , Segment , Label } from 'semantic-ui-react'
6
5
7
6
const source = _ . times ( 5 , ( ) => ( {
@@ -11,66 +10,89 @@ const source = _.times(5, () => ({
11
10
price : faker . finance . amount ( 0 , 100 , 2 , '$' ) ,
12
11
} ) )
13
12
14
- const resultRenderer = ( { title } ) => < Label content = { title } />
15
-
16
- resultRenderer . propTypes = {
17
- title : PropTypes . string ,
18
- description : PropTypes . string ,
13
+ const initialState = {
14
+ loading : false ,
15
+ results : [ ] ,
16
+ value : '' ,
19
17
}
20
18
21
- const initialState = { isLoading : false , results : [ ] , value : '' }
19
+ function exampleReducer ( state , action ) {
20
+ switch ( action . type ) {
21
+ case 'CLEAN_QUERY' :
22
+ return initialState
23
+ case 'START_SEARCH' :
24
+ return { ...state , loading : true , value : action . query }
25
+ case 'FINISH_SEARCH' :
26
+ return { ...state , loading : false , results : action . results }
27
+ case 'UPDATE_SELECTION' :
28
+ return { ...state , value : action . selection }
22
29
23
- export default class SearchExampleStandard extends Component {
24
- state = initialState
30
+ default :
31
+ throw new Error ( )
32
+ }
33
+ }
25
34
26
- handleResultSelect = ( e , { result } ) => this . setState ( { value : result . title } )
35
+ const resultRenderer = ( { title } ) => < Label content = { title } />
27
36
28
- handleSearchChange = ( e , { value } ) => {
29
- this . setState ( { isLoading : true , value } )
37
+ function SearchExampleStandardCustom ( ) {
38
+ const [ state , dispatch ] = React . useReducer ( exampleReducer , initialState )
39
+ const { loading, results, value } = state
30
40
31
- setTimeout ( ( ) => {
32
- if ( this . state . value . length < 1 ) return this . setState ( initialState )
41
+ const timeoutRef = React . useRef ( )
42
+ const handleSearchChange = React . useCallback ( ( e , data ) => {
43
+ clearTimeout ( timeoutRef . current )
44
+ dispatch ( { type : 'START_SEARCH' , query : data . value } )
33
45
34
- const re = new RegExp ( _ . escapeRegExp ( this . state . value ) , 'i' )
46
+ timeoutRef . current = setTimeout ( ( ) => {
47
+ if ( data . value . length === 0 ) {
48
+ dispatch ( { type : 'CLEAN_QUERY' } )
49
+ return
50
+ }
51
+
52
+ const re = new RegExp ( _ . escapeRegExp ( data . value ) , 'i' )
35
53
const isMatch = ( result ) => re . test ( result . title )
36
54
37
- this . setState ( {
38
- isLoading : false ,
55
+ dispatch ( {
56
+ type : 'FINISH_SEARCH' ,
39
57
results : _ . filter ( source , isMatch ) ,
40
58
} )
41
59
} , 300 )
42
- }
60
+ } , [ ] )
61
+ React . useEffect ( ( ) => {
62
+ return ( ) => {
63
+ clearTimeout ( timeoutRef . current )
64
+ }
65
+ } , [ ] )
43
66
44
- render ( ) {
45
- const { isLoading, value, results } = this . state
67
+ return (
68
+ < Grid >
69
+ < Grid . Column width = { 6 } >
70
+ < Search
71
+ loading = { loading }
72
+ onResultSelect = { ( e , data ) =>
73
+ dispatch ( { type : 'UPDATE_SELECTION' , selection : data . result . title } )
74
+ }
75
+ onSearchChange = { handleSearchChange }
76
+ resultRenderer = { resultRenderer }
77
+ results = { results }
78
+ value = { value }
79
+ />
80
+ </ Grid . Column >
46
81
47
- return (
48
- < Grid >
49
- < Grid . Column width = { 6 } >
50
- < Search
51
- loading = { isLoading }
52
- onResultSelect = { this . handleResultSelect }
53
- onSearchChange = { _ . debounce ( this . handleSearchChange , 500 , {
54
- leading : true ,
55
- } ) }
56
- results = { results }
57
- value = { value }
58
- resultRenderer = { resultRenderer }
59
- />
60
- </ Grid . Column >
61
- < Grid . Column width = { 10 } >
62
- < Segment >
63
- < Header > State</ Header >
64
- < pre style = { { overflowX : 'auto' } } >
65
- { JSON . stringify ( this . state , null , 2 ) }
66
- </ pre >
67
- < Header > Options</ Header >
68
- < pre style = { { overflowX : 'auto' } } >
69
- { JSON . stringify ( source , null , 2 ) }
70
- </ pre >
71
- </ Segment >
72
- </ Grid . Column >
73
- </ Grid >
74
- )
75
- }
82
+ < Grid . Column width = { 10 } >
83
+ < Segment >
84
+ < Header > State</ Header >
85
+ < pre style = { { overflowX : 'auto' } } >
86
+ { JSON . stringify ( { loading, results, value } , null , 2 ) }
87
+ </ pre >
88
+ < Header > Options</ Header >
89
+ < pre style = { { overflowX : 'auto' } } >
90
+ { JSON . stringify ( source , null , 2 ) }
91
+ </ pre >
92
+ </ Segment >
93
+ </ Grid . Column >
94
+ </ Grid >
95
+ )
76
96
}
97
+
98
+ export default SearchExampleStandardCustom
0 commit comments