Real-time search when a user stops typing

I need to search when the user stops typing. I know that I should use setTimeout () . But with Reactjs, I cannot find how this works. Can someone tell me how to call a method (which will handle the search) when the user stops typing for a few seconds (suppose 5). where to write code to verify that the user has stopped typing.

import React, {Component, PropTypes} from 'react'; export default class SearchBox extends Component { state={ name:" ", } changeName = (event) => { this.setState({name: event.target.value}); } sendToParent = () => { this.props.searching(this.state.name); } render() { return ( <div> <input type="text" placeholder='Enter name you wish to Search.' onChange={this.changeName} /> </div> ); } } 

I want to call the sendToParent method when the user stops typing.

+16
source share
6 answers

You can use setTimeout with respect to your code as follows:

 state = { name: '', typing: false, typingTimeout: 0 } changeName = (event) => { const self = this; if (self.state.typingTimeout) { clearTimeout(self.state.typingTimeout); } self.setState({ name: event.target.value, typing: false, typingTimeout: setTimeout(function () { self.sendToParent(self.state.name); }, 5000) }); } 

You also need to bind changeName handler in the constructor.

 constructor(props) { super(props); this.changeName = this.changeName.bind(this); } 
+20
source

Another way that worked with me:

 class Search extends Component { constructor(props){ super(props); this.timeout = 0; } doSearch(evt){ var searchText = evt.target.value; // this is the search text if(this.timeout) clearTimeout(this.timeout); this.timeout = setTimeout(() => { //search function }, 300); } render() { return ( <div className="form-group has-feedback"> <label className="control-label">Any text</label> <input ref="searchInput" type="text" onChange={evt => this.doSearch(evt)} /> </div> ); } } 
+7
source

Typeahead library issue https://twitter.imtqy.com/typeahead.js/

Since the case here is simple, I can use a quick and dirty solution:

 onChange: (event) -> if @_timeoutTask? clearTimeout @_timeoutTask @_timeoutTask = setTimeout (=> @sendToParent event.target.value clearTimeout @_timeoutTask ), 5000 

Thus, the task will be initiated 5 seconds after entering. If a new event occurs, the old task will be canceled and a new task will be scheduled, and then another 5 seconds of waiting.

The reagent difference is where the state of the calculation is stored, such as _timeoutTask . File scope, component state, or component instance.

Since _timeoutTask is a component level, it must be stored globally. And this does not affect the rendering, therefore it is not able to component either. Therefore, I suggest directly linking it to the component instance.

+1
source

you can just use debounce from lodash or simulate using setTimeout.

 import React, {Component, PropTypes} from 'react'; export default class SearchBox extends Component { constructor(props){ super(props); this.state={ name:" "} this.timeout = null; } changeName = (event) => { clearTimeout(timeout); if(timeout){ setTimeout((event)=> this.setState({name: event.target.value}), 200) } } sendToParent = () => { this.props.searching(this.state.name); } render() { return ( <div> <input type="text" placeholder='Enter name you wish to Search.' onChange={this.changeName} /> </div> ); } } 
0
source

I think we can do this in a simpler and cleaner way without interrupting the state parameter, which causes the componentโ€™s full life cycle, like this:

 constructor(props) { super(props); //Timer this.typingTimeout = null; //Event this.onFieldChange = this.onFieldChange.bind(this); //State this.state = { searchValue: '' }; } /** * Called on the change of the textbox. * @param {[Object]} event [Event object.] */ onFieldChange(event) { // Clears the previously set timer. clearTimeout(this.typingTimeout); // Reset the timer, to make the http call after 475MS (this.callSearch is a method which will call the search API. Don't forget to bind it in constructor.) this.typingTimeout = setTimeout(this.callSearch, 475); // Setting value of the search box to a state. this.setState({ [event.target.name]: event.target.value }); } <div className="block-header"> <input type="text" name="searchValue" value={this.state.searchValue} placeholder="User Name or Email" onChange={this.onFieldChange} /> </div> 
0
source

Lodash javascript user library and use [_.debounce][1]

 changeName: _.debounce(function (val) { console.log(val) }, 1000) 
0
source

Source: https://habr.com/ru/post/1014952/


All Articles