2016-07-25 10 views
1

Ich arbeite an einer Suchkomponente mit Auto-Vervollständigung-Funktion und ich bin in ein seltsames Verhalten. Die Komponente besteht aus einem Eingang (SearchInput) und einer Liste von Typ-Ahead-Ergebnissen (SearchResultWrapper).Reagieren onClick-Ereignis wird nicht abgeholt

Durch Klicken auf ein Schnelladressierungsergebnis wird das Feld SearchInput mit dem ausgewählten Ergebnis ausgefüllt und die Schnelladressierungsergebnisse ausgeblendet. Wenn Sie den Fokus auf das Feld verlieren, sollten Sie auch die Ergebnisse ausblenden.

Beispielcode finden Sie hier: https://jsfiddle.net/chez/h22qfx45/.

Das Problem tritt auf, wenn Sie in der closeResults-Funktion kommentieren, die für das Ändern des Status der Komponente verantwortlich ist, um die vorausgehenden Ergebnisse auszublenden. Wenn dieser Code aktiviert ist, wird der onClick-Handler für den SearchResult nicht mehr von React übernommen.

Es gibt offensichtlich ein grundlegendes Konzept, das ich hier vermisse. Hebt React das Trennen seiner Ereignis-Listener von der Komponente SearchResult auf, da diese ausgeblendet ist?

+0

Sie haben ein Rennen-Zustand ändern. Ändern Sie Ihre 'closeResults' in' setTimeout (() => this.setState ({resultsOpen: false}), 200); 'um es zu beobachten. Ich schätze, Sie verstecken das Element, bevor der Klick registriert wird (denken Sie daran, dass der Browser den Fokus entfernt, bevor er ein Klickereignis auslösen kann). Ich habe momentan keine Zeit, es genauer zu betrachten, aber vielleicht hilft es. – ivarni

+0

Es wäre schön, wenn Sie den Teil des Codes veröffentlichen könnten, der am verwirrendsten ist oder den Sie für den wichtigsten halten. – HoldOffHunger

Antwort

4

Es gibt eine Sache in JS: onBlur heißt vor onClick.

Um es zu lösen, müssen Sie nur onClick durch onMouseDown ersetzen.

Hier ist der Code: https://jsfiddle.net/h22qfx45/5/

Quelle:onclick() and onblur() ordering issue

+1

Nicht wirklich ein Problem mit React AFAIK, das ist nur die Reihenfolge, in der die Dinge im Browser passieren. Reagieren passiert einfach schnell genug (harr), dass es wichtig ist :) – ivarni

+0

Ich ersetze _issue_ durch _thing_. Danke für die Informationen :) –

+1

Es ist ein Javascript * Ding * wirklich. – Chris

1

Vergessen Sie die onBlur Ereignis. OnBlur ist nicht, wenn Sie Ihren Inhalt verbergen wollen. Sie beabsichtigen, Ihren Inhalt zu verbergen, sobald eine Auswahl getroffen wurde. Also würde ich vorschlagen, dass Sie die Methode closeResults() sowie das Ereignis onBlur vollständig entfernen. Von dort aus möchten Sie die Methode handleSearchResultClick() ändern, um den Sichtbarkeitsstatus der Ergebnisse zu ändern.

Ich habe eine aktualisierte Fiddle, die das tut, was Sie suchen here.

Kurz: entfernen diese:

onBlur={this.closeResults} 

closeResults() { 
//this.setState({resultsOpen: false}); 
}, 

und

handleSearchResultClick(event) { 
    var selectedResult = event.target.innerText; 
    this.setState({searchString: selectedResult}); 
}, 

zu

handleSearchResultClick(event) { 
    var selectedResult = event.target.innerText; 
    this.setState({searchString: selectedResult, resultsOpen: false}); 
}, 
+0

Das obige Beispiel ist also ein Feld, das eine größere Form zusammensetzt. Es ist möglich, dass der Benutzer den Fokus auf ein anderes Feld verschiebt, ohne eine Auswahl zu treffen. 'onBlur' schien ein guter Auslöser zu sein, um die Ergebnisse zu schließen, die nicht von einer komponentenübergreifenden Kommunikation abhängig waren ... – Nitax