This example demonstrates how to add a 1sec debounce, so that suggestions are retrieved only after user stopped typing for 1sec.
A Pen by mike lange on CodePen.
This example demonstrates how to add a 1sec debounce, so that suggestions are retrieved only after user stopped typing for 1sec.
A Pen by mike lange on CodePen.
<h2>Debouncing</h2> | |
<div id="app"></div> |
/* ---------- */ | |
/* Data */ | |
/* ---------- */ | |
const languages = [ | |
{ | |
name: 'C', | |
year: 1972 | |
}, | |
{ | |
name: 'C#', | |
year: 2000 | |
}, | |
{ | |
name: 'C++', | |
year: 1983 | |
}, | |
{ | |
name: 'Clojure', | |
year: 2007 | |
}, | |
{ | |
name: 'Elm', | |
year: 2012 | |
}, | |
{ | |
name: 'Go', | |
year: 2009 | |
}, | |
{ | |
name: 'Haskell', | |
year: 1990 | |
}, | |
{ | |
name: 'Java', | |
year: 1995 | |
}, | |
{ | |
name: 'Javascript', | |
year: 1995 | |
}, | |
{ | |
name: 'Perl', | |
year: 1987 | |
}, | |
{ | |
name: 'PHP', | |
year: 1995 | |
}, | |
{ | |
name: 'Python', | |
year: 1991 | |
}, | |
{ | |
name: 'Ruby', | |
year: 1995 | |
}, | |
{ | |
name: 'Scala', | |
year: 2003 | |
} | |
]; | |
function getMatchingLanguages(value) { | |
const escapedValue = escapeRegexCharacters(value.trim()); | |
if (escapedValue === '') { | |
return []; | |
} | |
const regex = new RegExp('^' + escapedValue, 'i'); | |
return languages.filter(language => regex.test(language.name)); | |
} | |
/* ----------- */ | |
/* Utils */ | |
/* ----------- */ | |
// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Special_Characters | |
function escapeRegexCharacters(str) { | |
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); | |
} | |
function randomDelay() { | |
return 300 + Math.random() * 1000; | |
} | |
/* --------------- */ | |
/* Component */ | |
/* --------------- */ | |
function getSuggestionValue(suggestion) { | |
return suggestion.name; | |
} | |
function renderSuggestion(suggestion) { | |
return ( | |
<span>{suggestion.name}</span> | |
); | |
} | |
class App extends React.Component { | |
constructor() { | |
super(); | |
this.state = { | |
value: '', | |
suggestions: [], | |
isLoading: false | |
}; | |
this.debouncedLoadSuggestions = _.debounce(this.loadSuggestions, 1000); // 1000ms is chosen for demo purposes only. | |
} | |
loadSuggestions(value) { | |
this.setState({ | |
isLoading: true | |
}); | |
// Fake an AJAX call | |
setTimeout(() => { | |
const suggestions = getMatchingLanguages(value); | |
if (value === this.state.value) { | |
this.setState({ | |
isLoading: false, | |
suggestions | |
}); | |
} else { // Ignore suggestions if input value changed | |
this.setState({ | |
isLoading: false | |
}); | |
} | |
}, randomDelay()); | |
} | |
onChange = (event, { newValue }) => { | |
this.setState({ | |
value: newValue | |
}); | |
}; | |
onSuggestionsFetchRequested = ({ value }) => { | |
this.debouncedLoadSuggestions(value); | |
}; | |
onSuggestionsClearRequested = () => { | |
this.setState({ | |
suggestions: [] | |
}); | |
}; | |
render() { | |
const { value, suggestions, isLoading } = this.state; | |
const inputProps = { | |
placeholder: "Type 'c'", | |
value, | |
onChange: this.onChange | |
}; | |
const status = (isLoading ? 'Loading...' : 'Type to load suggestions'); | |
return ( | |
<div> | |
<div className="status"> | |
<strong>Status:</strong> {status} | |
</div> | |
<Autosuggest | |
suggestions={suggestions} | |
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested} | |
onSuggestionsClearRequested={this.onSuggestionsClearRequested} | |
getSuggestionValue={getSuggestionValue} | |
renderSuggestion={renderSuggestion} | |
inputProps={inputProps} /> | |
</div> | |
); | |
} | |
} | |
ReactDOM.render(<App />, document.getElementById('app')); |
<script src="https://unpkg.com/[email protected]/dist/react.js"></script> | |
<script src="https://unpkg.com/[email protected]/dist/react-dom.js"></script> | |
<script src="https://unpkg.com/[email protected]/dist/standalone/autosuggest.js"></script> | |
<script src="https://unpkg.com/[email protected]/lodash.js"></script> |
body { | |
font-family: Helvetica, sans-serif; | |
} | |
.status { | |
line-height: 52px; | |
} | |
.react-autosuggest__container { | |
position: relative; | |
} | |
.react-autosuggest__input { | |
width: 240px; | |
height: 30px; | |
padding: 10px 20px; | |
font-family: Helvetica, sans-serif; | |
font-weight: 300; | |
font-size: 16px; | |
border: 1px solid #aaa; | |
border-radius: 4px; | |
} | |
.react-autosuggest__input--focused { | |
outline: none; | |
} | |
.react-autosuggest__input--open { | |
border-bottom-left-radius: 0; | |
border-bottom-right-radius: 0; | |
} | |
.react-autosuggest__suggestions-container { | |
display: none; | |
} | |
.react-autosuggest__suggestions-container--open { | |
display: block; | |
position: absolute; | |
top: 51px; | |
width: 280px; | |
border: 1px solid #aaa; | |
background-color: #fff; | |
font-family: Helvetica, sans-serif; | |
font-weight: 300; | |
font-size: 16px; | |
border-bottom-left-radius: 4px; | |
border-bottom-right-radius: 4px; | |
z-index: 2; | |
} | |
.react-autosuggest__suggestions-list { | |
margin: 0; | |
padding: 0; | |
list-style-type: none; | |
} | |
.react-autosuggest__suggestion { | |
cursor: pointer; | |
padding: 10px 20px; | |
} | |
.react-autosuggest__suggestion--highlighted { | |
background-color: #ddd; | |
} |