1- import PropTypes from 'prop-types'
21import _ from 'lodash'
32import faker from 'faker'
4- import React , { Component } from 'react'
3+ import React from 'react'
54import { Search , Grid , Header , Segment , Label } from 'semantic-ui-react'
65
76const source = _ . times ( 5 , ( ) => ( {
@@ -11,66 +10,89 @@ const source = _.times(5, () => ({
1110 price : faker . finance . amount ( 0 , 100 , 2 , '$' ) ,
1211} ) )
1312
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 : '' ,
1917}
2018
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 }
2229
23- export default class SearchExampleStandard extends Component {
24- state = initialState
30+ default :
31+ throw new Error ( )
32+ }
33+ }
2534
26- handleResultSelect = ( e , { result } ) => this . setState ( { value : result . title } )
35+ const resultRenderer = ( { title } ) => < Label content = { title } />
2736
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
3040
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 } )
3345
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' )
3553 const isMatch = ( result ) => re . test ( result . title )
3654
37- this . setState ( {
38- isLoading : false ,
55+ dispatch ( {
56+ type : 'FINISH_SEARCH' ,
3957 results : _ . filter ( source , isMatch ) ,
4058 } )
4159 } , 300 )
42- }
60+ } , [ ] )
61+ React . useEffect ( ( ) => {
62+ return ( ) => {
63+ clearTimeout ( timeoutRef . current )
64+ }
65+ } , [ ] )
4366
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 >
4681
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+ )
7696}
97+
98+ export default SearchExampleStandardCustom
0 commit comments