How to start search only when user stops typing?

后端 未结 10 1774

I need to perform a Search when user stops typing.I know I am supposed to use setTimeout() . But with Reactjs I cant find how it works. Can

相关标签:
10条回答
  • 2020-12-07 18:50

    This library (use-debounce) is nice and simple.

    Setup

    yarn add use-debounce
    

    or

    npm i use-debounce --save
    

    Usage sample from documentation

    import React, { useState } from 'react';
    import { useDebounce } from 'use-debounce';
    
    export default function Input() {
      const [text, setText] = useState('Hello');
      const [value] = useDebounce(text, 1000);
    
      return (
        <div>
          <input
            defaultValue={'Hello'}
            onChange={(e) => {
              setText(e.target.value);
            }}
          />
          <p>Actual value: {text}</p>
          <p>Debounce value: {value}</p>
        </div>
      );
    }
    

    Things that I liked at this moment, things could be different in future!:

    • Easy to setup & use
    • Less Boilerplate code
    • Modest ratings (~1K) and usage (npm - 200K downloads/Week)
    • Supports timeout, MaxWait and other features
    0 讨论(0)
  • 2020-12-07 18:53

    Problem of Typeahead library https://twitter.github.io/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
    

    In this way, the task will be triggered 5s after input event. If new event happens, the old task will be cancelled and a new task is scheduled, then it's another 5s to wait.

    The difference in React is the where to store the computation state like _timeoutTask. The file scope, the component state, or the component instance.

    Since _timeoutTask is component level, it should be be store globally. And it does not affect rendering, so not in component state too. So I suggest attaching it to component instance directly.

    0 讨论(0)
  • 2020-12-07 18:55

    User lodash javascript library and use [_.debounce][1]

    changeName: _.debounce(function (val) {
      console.log(val)                
    }, 1000)
    
    0 讨论(0)
  • 2020-12-07 18:57

    I think we can do it in a more simpler and cleaner manner, without abrupting the state parameter which calls the complete component 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 讨论(0)
  • 2020-12-07 18:59

    you can just use the 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 讨论(0)
  • 2020-12-07 19:02

    I used the debounce function of lodash

    onChangeSearchInput = (evt)=> {
        this.debouncedSearch(evt.target.value);
    };
    
    debouncedSearch = debounce(function (query) {
        this.setState({query});
    }, 1000);
    

    Somewhere in my render method i have this input field

    <input
        type='text'
        onChange={this.onChangeSearchInput}
        className='uk-input'
        placeholder={'search by name or email...'}
       />
    
    0 讨论(0)
提交回复
热议问题