title: Reactjs Search after onChange
body: <p>I have implemented a little search functionality in my reactjs application. 
  The Problem is, that my "searchHandler" function is triggered after every single letter the user enters in the textfield... So e.g. for the term "Lorem" my function is fetching 5 times from my api :(</p>
  
  <p>How can I solve this problem?</p>
  
  <p>Here is my code:</p>
  
  <pre><code>const { scaleDown } = transitions;
  
  function searchingFor(term){
  
  return function(x){
  return x.title.toLowerCase().includes(term.toLowerCase()) ||
  x.body.toLowerCase().includes(term.toLowerCase());
  }
  
   }  
  
  
  class ViewAll extends React.Component{
  
  constructor(props){
    super(props);
    this.state = {
      term: '',
      mounted: true,
      tracks: [],
      hasMoreItems: true,
      page: 2,
  
    }
  
    this.searchHandler = this.searchHandler.bind(this);
    this.focus = this.focus.bind(this);
    this.keyPress = this.keyPress.bind(this);
  
  
   }
  
    loadContent() {
      var requestUrl = this.props.url;
      fetch(requestUrl + this.state.page + '&amp;_limit=3').then((response)=&gt;{
          return response.json();
      }) .then((tracks)=&gt;{
          this.setState({ tracks: this.state.tracks.concat(tracks)});
          this.setState({page: this.state.page + 1});
  
          if(this.state.page === 6){
           this.setState({hasMoreItems: false})
         }
      }).catch((err)=&gt;{
          console.log("There has been an error");
      });
  }
  
  componentDidMount() {
    window.scrollTo(0, 0);
  
  var requestUrl = this.props.url;
  fetch(requestUrl + '1&amp;_limit=3')
      .then((response)=&gt;{
      return response.json();
  }) .then((data)=&gt;{
      this.setState({tracks : data});
  
  })
  .catch((err)=&gt;{
      console.log("There has been an error");
  });
  
  //this.focus();
  
   }
    searchHandler(event){
      this.setState({term: event.target.value});
  
      var requestUrl = 'https://questdb.herokuapp.com/all?q='
      fetch(requestUrl + this.state.term).then((response)=&gt;{
          return response.json();
      }) .then((tracks)=&gt;{
          this.setState({ tracks: this.state.tracks.concat(tracks)});
  
  
      }).catch((err)=&gt;{
          console.log("There has been an error");
      });
  
    }
  
     focus() {
     this.textInput.focus();
   }
  
  
      keyPress(e){
         if(e.keyCode == 13){
            console.log('value', e.target.value);
            // put the login here
         }
      }    
  
  
  render() {   
  
  
    const {term, data, tracks} = this.state;
  
    const loader = &lt;div className="loader2"&gt; &lt;/div&gt;;
  
    var items = [];
    const imageUrl = require(`../assets/Book.jpg`)
  
    tracks.filter(searchingFor(term)).map(function(title, i)
  {
      items.push(
              &lt;div&gt;
                &lt;MuiThemeProvider&gt;
                  &lt;Paper style={{ borderRadius: "2em",
                    background: '#ffffff'
                  }} zDepth={1} &gt;
  
            &lt;ItemViewAll
              key={title.id}
                /&gt;
        &lt;/Paper&gt;
        &lt;/MuiThemeProvider&gt;
        &lt;/div&gt;
      );
    }, this);
  
  
  
      return (
        &lt;div&gt;    
  
              &lt;Fade in={true}  timeout={1000}&gt;
  
  &lt;div &gt;
  
    &lt;MuiThemeProvider&gt;
  
      &lt;TextField hintText='Bot suchen...'
  
           type="Text"
           onChange={this.searchHandler}
           value={term}
           underlineFocusStyle={{borderColor: '#B00020', borderWidth: 3}}
           underlineStyle={{borderColor: '#B00020', borderWidth: 1.5, top: '45px'}}
           hintStyle={{fontSize: '8.1vw', fontFamily: 'Anton', color: 'rgba(255,255,255,0.9)'}}
           inputStyle={{fontSize: '8.1vw', fontFamily: 'Anton', color: '#ffffff'}}
           ref={(input) =&gt; { this.textInput = input; }}
           style={{caretColor: '#ffffff', width: '90%', maginLeft: 'auto', marginRight: 'auto', marginTop: '12%' }}
           InputLabelProps={{ shrink: true }}
           /&gt;
  
  
       &lt;/MuiThemeProvider&gt;
        &lt;/div&gt;
        &lt;/Fade&gt;   
  
  
  
      &lt;InfiniteScroll
         pageStart={1}
         loadMore={this.loadContent.bind(this)}
         hasMore={this.state.hasMoreItems}
         initialLoad={true}
  
        &gt;
  
  
                {items}
           &lt;/InfiniteScroll&gt;    
  
  
  &lt;/div&gt;
      )
    }
  }
  
  export default ViewAll;
  </code></pre>
  
  <p>Here you can check out the Website with the broken search function. As you can see the items are shown double or even triple... After the textfield is emptied, the search results should be removed and only the normal fetched ones should be shown.</p>
  
  <p><a href="https://www.genko.de" rel="nofollow noreferrer">https://www.genko.de</a>   (use the mobile version in chrome)</p>
  
  <p>Thank you :)</p>