Erstellen eines Reactive UsePosition () - Hooks zum Abrufen und Verfolgen von Browserkoordinaten

Bild


Wenn kurz


In diesem Artikel erstellen wir einen reaktiven Hook usePosition() , um die usePosition() Browsers zu verfolgen. Unter der Haube verwendet dieser Hook die getCurrentPosition() und watchPosition() des nativen Browserobjekts navigator.geolocation . Ich habe die endgültige Version des Hooks auf GitHub und NPM veröffentlicht .


Warum grundsätzlich einen usePosition() Hook erstellen usePosition()


Einer der wichtigen Vorteile von Hooks in React ist die Möglichkeit, logisch verwandte Codefragmente an einer Stelle (im Hook) zu isolieren, ohne logisch nicht verwandte Codefragmente zu mischen, z. B. in der componentDidMount() -Methode der Komponente.


Angenommen, wir möchten die Browserkoordinaten ( latitude und latitude longitude und nach Erhalt der Koordinaten eine Wettervorhersage oder die aktuelle Temperatur in dieser Region von einem Drittanbieter anfordern. Der Code dieser beiden Funktionen (Erhalten von Koordinaten und Anfordern der Temperatur) in React wird häufig in einer componentDidMount() -Methode platziert. In diesem Fall wird die componentWillUnmount() -Methode normalerweise von selbst "bereinigt" und ruft die clearWatch () -Methode auf, um die Überwachung des Browserstandorts zu beenden. Ein solcher Ansatz erhöht die Größe von Methoden, teilt logisch verbundene Codeabschnitte in Teile auf (getrenntes Abonnieren und Abbestellen von der Überwachung des Standorts des Browsers) und kombiniert logisch schwach verbundene Teile des Codes zu einer Methode (Erhalten von Koordinaten und Temperatur). Das Lesen von Code ist schwierig, ebenso wie das Debuggen und die Unterstützung.


Als nächstes werden wir versuchen, die mit dem usePosition() der Koordinaten des Browsers verbundenen Funktionen in einen separaten usePosition() Hook zu übertragen, um die oben aufgeführten Schwierigkeiten zu vermeiden.


Wie werden wir den usePosition() Hook verwenden usePosition()


Gehen wir „vom Gegenteil“ und planen wir vor der Implementierung des Hooks selbst, wie wir ihn verwenden werden. Dies hilft uns bei der Bestimmung der Hook-Schnittstelle (was akzeptiert wird und was zurückgegeben werden soll).


Das einfachste Beispiel für das Abrufen und Anzeigen von Koordinaten auf dem Bildschirm könnte folgendermaßen aussehen:


 import React from 'react'; //    . import { usePosition } from './usePosition'; export const UsePositionDemo = () => { //    ( ) . const { latitude, longitude, error } = usePosition(); //       (   ). return ( <> latitude: {latitude}, longitude: {longitude}, error: {error} </> ); }; 

Nur eine Zeile mit dem usePosition() und wir können mit latitude und latitude arbeiten. Wir haben hier noch nicht einmal explizit die Hooks useState() oder useEffect() . Ein Abonnement zum Verfolgen von Koordinaten sowie das Löschen eines Abonnenten sind in einem usePosition() Hook zusammengefasst. Darüber hinaus wird die Magie des Neuzeichnens von React-Komponenten alles für uns tun. Zu Beginn sind die Koordinaten null oder undefined . Sobald die Koordinaten empfangen wurden, wird die Komponente neu gezeichnet und wir sehen sie auf dem Bildschirm.


usePosition() Implementierung usePosition()


Unser usePosition() Hook ist eine reguläre JavaScript-Funktion, die folgendermaßen aussieht:


 //  . export const usePosition = () => { //    . } 

Wir werden die Hooks useState () zum internen Speichern von Koordinaten und useEffect () zum Abonnieren und Abbestellen von Tracking-Koordinaten verwenden. Dazu müssen wir sie importieren.


 import { useState, useEffect } from 'react'; export const usePosition = () => { //     . } 

Wir erstellen Statusvariablen, in denen wir Koordinaten oder einen Fehler beim Abrufen von Koordinaten speichern (z. B. wenn der Benutzer sich weigert, seinen Standort freizugeben).


 import { useState, useEffect } from 'react'; export const usePosition = () => { const [position, setPosition] = useState({}); const [error, setError] = useState(null); //  ... } 

Auch in dieser Phase können wir die Variablen zurückgeben, die vom Hook erwartet werden. Bisher sind diese Variablen nicht nützlich, aber wir werden sie bald beheben.


 import { useState, useEffect } from 'react'; export const usePosition = () => { const [position, setPosition] = useState({}); const [error, setError] = useState(null); // other code goes here... return { ...position, error }; } 

Und jetzt ist der entscheidende Moment der Implementierung das Erhalten von Koordinaten.


 import { useState, useEffect } from 'react'; export const usePosition = () => { const [position, setPosition] = useState({}); const [error, setError] = useState(null); //     ,    .. useEffect(() => { const geo = navigator.geolocation; if (!geo) { setError('   '); return; } //     . watcher = geo.watchPosition(onChange, onError); //  ,       //    ,    . return () => geo.clearWatch(watcher); }, []); return {...position, error}; } 

Im useEffect() Hook prüfen wir zunächst, ob der Browser die Koordinatenerkennungsfunktion unterstützt. Wenn die Funktionalität nicht unterstützt wird, verlassen wir den Hook mit einem Fehler. Andernfalls abonnieren wir die Änderung der Geolokalisierung des Browsers mithilfe der Rückrufe onChange onChange() und onError() (wir werden den folgenden Code hinzufügen). Beachten Sie, dass wir vom useEffect() Hook eine anonyme Funktion zurückgeben, die ausgeführt wird, wenn die Komponente aus der Anzeige entfernt wird. In dieser anonymen Funktion melden wir uns von der Überwachung ab, um den Speicher nicht zu verstopfen. Somit befindet sich die gesamte Logik des Abonnierens und Abbestellens von Tracking in einem usePosition() Hook.


Fügen wir die fehlenden Rückrufe hinzu:


 import { useState, useEffect } from 'react'; export const usePosition = () => { const [position, setPosition] = useState({}); const [error, setError] = useState(null); const onChange = ({latitude, longitude}) => { //        position,   //    ,    . setPosition({latitude, longitude}); }; const onError = (error) => { setError(error.message); }; useEffect(() => { const geo = navigator.geolocation; if (!geo) { setError('   '); return; } //     . watcher = geo.watchPosition(onChange, onError); //  ,       //    ,    . return () => geo.clearWatch(watcher); }, []); return {...position, error}; } 

Der usePosition() Hook ist einsatzbereit.


Am Ende


Sie finden eine Demonstration des Hooks und seiner detaillierteren Implementierung mit der Möglichkeit, Tracking-Parameter auf GitHub festzulegen .


Ich hoffe, dieser Artikel hat Ihnen geholfen. Erfolgreiche Codierung!

Source: https://habr.com/ru/post/de458614/


All Articles