2017-02-14 3 views
5

Ich muss eine Suche durchführen, wenn der Benutzer die Eingabe beendet. Ich weiß, dass ich setTimeout() verwenden soll. Aber mit Reactjs kann ich nicht finden, wie es funktioniert. Kann mir bitte jemand sagen, wie man eine Methode aufruft (die die Suche behandelt), wenn der Benutzer für ein paar Sekunden aufhört zu tippen (angenommen 5). Ich kann nicht herausfinden, wo der Code geschrieben werden muss, um zu überprüfen, dass der Benutzer die Eingabe beendet hat.Suchen in Reagieren, wenn Benutzer mit der Eingabe aufhört

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> 
     ); 
    } 
} 

Ich möchte die sendToParent-Methode aufrufen, wenn der Benutzer die Eingabe beendet.

+0

Nun sind sie in einem Eingangselement eingeben? Wenn dies der Fall ist, haben Eingabeelemente ein Attribut mit dem Namen onKeyPress, das jedes Mal aufgerufen wird, wenn sie eine Schaltfläche drücken, während diese Eingabe ausgewählt ist. Sie können also festlegen, dass die Zeitüberschreitung bei jedem Drücken einer Taste gestartet wird, aber wenn die Taste erneut gedrückt wird, bevor die Zeitüberschreitung ausgeführt wurde, wird die Zeit zurückgesetzt. Wenn sie X Zeit nicht eingegeben haben, führt das Timeout eine Suche aus. – Jayce444

+0

Wenn Sie sich auf den eigentlichen Code beziehen, der die Zeitüberschreitungssuche und die 'gestopptes Tippen' prüft, dann gibt es viele Beispiele für diese online. – Jayce444

+0

Meine Methode ruft nicht auf onkeyPress – shinite

Antwort

8

Sie setTimeout in Bezug auf Ihrem Code verwenden können wie folgt

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) 
    }); 
} 

Außerdem müssen Sie changeName Handler-Funktion in Konstruktor binden.

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

Danke, dass es funktioniert .. :) – shinite

+1

Ich bin zu spät zur Party, aber ich möchte darauf hinweisen, dass Sie die ChangeName-Funktion nicht binden müssen, wenn Sie es6 Pfeilsyntax verwenden. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – MEnf

+0

Aus demselben Grund müssen Sie 'const self = this' nicht setzen. "Dies" ist bereits an den Klassenumfang gebunden. – MEnf

1

Problem von typeahead Bibliothek https://twitter.github.io/typeahead.js/

Da hier der Fall einfach ist, kann ich eine schnelle und schmutzige Lösung verwenden:

onChange: (event) -> 
    if @_timeoutTask? 
    clearTimeout @_timeoutTask 

    @_timeoutTask = setTimeout (=> 
    @sendToParent event.target.value 
    clearTimeout @_timeoutTask 
), 5000 

Auf diese Weise wird die Aufgabe ausgelöst wird 5s nach Eingabe-Ereignisse. Wenn ein neues Ereignis eintritt, wird die alte Aufgabe abgebrochen und eine neue Aufgabe wird geplant, dann warten weitere 5 Sekunden.

Der Unterschied in React ist, wo der Berechnungszustand wie _timeoutTask gespeichert werden soll. Der Dateibereich, der Komponentenstatus oder die Komponenteninstanz.

Da _timeoutTask Komponentenebene ist, sollte es global gespeichert werden. Und es wirkt sich nicht auf das Rendering aus, also auch nicht auf den Komponentenstatus. Daher empfehle ich, sie direkt an die Komponenteninstanz anzuhängen.

0

Sie können einfach das Debounce von lodash verwenden oder simulieren mit 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> 
     ); 
    } 
} 
2

Eine andere Art und Weise, die mit mir gearbeitet:

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> 
    ); 
    } 
} 
Verwandte Themen