• Zuhause
  • Artikel
  • Wie erkennt man einen Außenklick mit Reagieren und Haken?
Veröffentlicht am 28-02-2019

Wie erkennt man einen Außenklick mit Reagieren und Haken?

Foto von Alex Block auf Unsplash

Was bedeutet "Outside Click"?

Sie können es sich als "Anti-Knopf" vorstellen. Ein Klick von außen ist ein Weg, um zu wissen, ob der Benutzer auf alles ABER eine bestimmte Komponente klickt. Dieses Verhalten ist möglicherweise aufgetreten, wenn Sie ein Dropdown-Menü oder eine Dropdown-Liste öffnen und außerhalb davon klicken, um es zu schließen.

Es gibt alle möglichen anderen Anwendungsfälle für eine solche Funktion:

  • beim Schließen von Dropdown-Listen
  • beim Schließen modaler Fenster
  • beim Übergang in den Bearbeitungsmodus und aus dem Bearbeitungsmodus für bearbeitbare Elemente
  • Schließen
  • und viele mehr…

Nun wollen wir sehen, wie wir eine generische und wiederverwendbare React-Komponente schreiben können, die dieses Verhalten berücksichtigt.

Wie wird es aussehen?

Ein glücklicher Fluss sollte so aussehen:

Komponentenstruktur

Damit diese Komponente funktioniert, müssen wir einen Klick-Ereignishandler im Dokument selbst anfügen. Dies hilft uns zu erkennen, wenn wir irgendwo auf die Seite klicken. Dann müssen wir prüfen, ob sich unser angeklicktes Ziel von unserem umwickelten Element unterscheidet. Eine Grundstruktur sieht also so aus:

Für das erste Beispiel beginnen wir mit dem Codieren mit dem Stil "React Class" und formatieren es anschließend mit der neuen Hooks-API.

Wir haben zwei Lebenszyklusfunktionen implementiert:

  • componentDidMount (): fügt den Ereignis-Listener hinzu
  • componentWillUnmount (): Bereinigt den Click-Handler, bevor die Komponente zerstört wird
  • und dann rendern wir, was immer die Komponenten umhüllen. Für unser erstes Beispiel oben wird das gerendert.

    Die Bedingung "ClickOutside"

    Jetzt müssen wir überprüfen, ob der Benutzer außerhalb des umwickelten untergeordneten Objekts klickt. Eine naive Lösung besteht darin, das Zielelement (das Element, auf das wir klicken) mit dem Knoten unseres Kindes zu vergleichen. Dies funktioniert jedoch nur, wenn wir als Kind einen einfachen (einstufigen) Knoten haben. Wenn unser umwickeltes Kind mehr Unterknoten hat, schlägt diese Lösung fehl.

    Glücklicherweise gibt es eine Methode namens .contains (), die uns sagt, ob ein Knoten ein Kind eines bestimmten Knotens ist. Im nächsten Schritt erhalten Sie Zugriff auf den Knoten unseres Kindes. Um dies zu erreichen, verwenden wir React Refs.

    Refs sind der Weg von React, uns Zugriff auf das rohe Knotenobjekt zu gewähren. Wir werden auch die Reacts-API für die Handhabung der this.props.children-Komponenten verwenden. Wir brauchen diese API, weil wir unserem umhüllten Kind unseren erstellten Hinweis hinzufügen werden. Vor diesem Hintergrund wird unsere Komponente so aussehen:

    Perfekt, das sollte wie erwartet funktionieren. Zumindest für unseren glücklichen Fluss (ein eingewickeltes Kind). Wenn wir beabsichtigen, mehr als einen Knoten zu binden, müssen wir einige Anpassungen vornehmen:

    • Wir brauchen eine Reihe von Refs (so viele wie unsere eingewickelten Kinder)
    • Wir müssen React.Children.map verwenden, um jedes Kind zu klonen und den zugehörigen ref aus unserem privaten Array von refs einzufügen

    Das sollte gut gehen. Jetzt wollen wir dies mit Hooks umgestalten!

    Haken

    In Reaktion 16.8 wurde eine neue API namens Hooks eingeführt. Mit Hooks können wir weniger Code schreiben und einen kleineren Footprint in unserer Codebase erhalten. Außerdem nutzen Hooks Funktionen, die in JavaScript erstklassige Bürger sind. Wenn Sie mit statusfreien Funktionskomponenten von React vertraut sind, sind Sie auf halbem Weg. Unser anfänglicher Refaktor wird so aussehen:

    Bis jetzt verwenden wir immer noch die "alte" React-API, um eine einfache zustandslose Funktionskomponente zu deklarieren. Wir benötigen jedoch immer noch diese Lebenszyklusfunktionen, um unseren Handler an den Dokumentknoten anzuhängen.

    Hier kommt der Effect-Hook zum Einsatz. Der Effect-Hook ersetzt unsere Methoden „componentDidMount“ und „componentWillUnmount“. Der Effekt-Hook wird direkt nach dem Rendern der Komponenten aufgerufen, sodass wir unseren gewünschten Handler rechtzeitig anbringen können. Wenn der Effect-Hook eine Funktion zurückgibt, wird diese Funktion direkt vor dem Aufheben der Bereitstellung der Komponente aufgerufen. Es ist also genau der richtige Zeitpunkt, um eine Bereinigung durchzuführen. Im nächsten Refactor werden die Dinge ein bisschen klarer.

    Dies ist die endgültige Form unserer Funktionskomponente, die den Effekthaken verwendet. Wenn Sie beide Beispiele in Aktion sehen möchten, können Sie sie unten ausführen. (Sie können standardmäßig entweder die Klassenkomponente oder die Funktionskomponente exportieren, und die App verhält sich gleich.)

    Fazit

    Auch wenn das Verhalten beim Klicken außerhalb des Bereichs häufig verwendet wird, ist die Implementierung in React möglicherweise nicht so einfach. Mit diesem Beispiel habe ich mir die Freiheit genommen, ein wenig mit React Hooks zu experimentieren und die Lösung auf zwei Arten zu erstellen, um die beiden Ansätze zu vergleichen. Ich bin ein großer Fan von funktionalen Komponenten, und jetzt können wir sie mithilfe von Hooks auf die nächste Stufe bringen.