Crear un enlace Reactivo UsePosition () para obtener y rastrear las coordenadas del navegador

imagen


Si brevemente


En este art铆culo, crearemos un usePosition() reactivo usePosition() para rastrear la geolocalizaci贸n del navegador. Bajo el cap贸, este gancho utilizar谩 los getCurrentPosition() y watchPosition() del objeto de navegador nativo navigator.geolocation . Publiqu茅 la versi贸n final del gancho en GitHub y NPM .


驴Por qu茅 crear un gancho usePosition() en principio


Una de las ventajas importantes de los ganchos en React es la capacidad de aislar fragmentos de c贸digo relacionados l贸gicamente en un lugar (en el gancho), evitando la necesidad de mezclar fragmentos de c贸digo no relacionados l贸gicamente, por ejemplo, en el m茅todo componentDidMount() del componente.


Supongamos que queremos obtener las coordenadas del navegador ( latitude y longitude ) y despu茅s de recibir las coordenadas, solicite el pron贸stico del tiempo o la temperatura actual en esta regi贸n a un servicio externo. El c贸digo de estas dos funcionalidades (obtenci贸n de coordenadas y solicitud de temperatura) en React a menudo se coloca dentro de un m茅todo componentDidMount() . En este caso, el m茅todo componentWillUnmount() generalmente se "limpia" por s铆 solo, llamando al m茅todo clearWatch () para dejar de monitorear la ubicaci贸n del navegador. Tal enfoque aumenta el tama帽o de los m茅todos, divide secciones de c贸digo conectadas l贸gicamente en partes (suscribiendo y cancelando por separado la supervisi贸n de la ubicaci贸n del navegador), y combina partes del c贸digo conectadas l贸gicamente d茅bilmente en un m茅todo (obteniendo coordenadas y temperatura). Leer el c贸digo es dif铆cil, como lo es la depuraci贸n y el soporte.


A continuaci贸n, intentaremos transferir la funcionalidad asociada con la obtenci贸n de las coordenadas del navegador en un gancho usePosition() separado para evitar las dificultades mencionadas anteriormente.


驴C贸mo usaremos el gancho usePosition()


Vayamos "desde el opuesto" y antes de implementar el gancho en s铆 mismo, planeemos c贸mo lo usaremos. Esto nos ayudar谩 a determinar la interfaz de enlace (qu茅 aceptar谩 y qu茅 devolver).


El ejemplo m谩s simple de obtener coordenadas y mostrarlas en la pantalla podr铆a verse as铆:


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

Solo una l铆nea con el gancho usePosition() y podemos operar con coordenadas de latitude y longitude . Ni siquiera useState() usado expl铆citamente los ganchos useState() o useEffect() aqu铆. Una suscripci贸n a las coordenadas de seguimiento, as铆 como la eliminaci贸n de un suscriptor, se encapsulan en un usePosition() . Adem谩s, la magia de volver a dibujar los componentes de React har谩 todo por nosotros. Al principio, las coordenadas ser谩n null o undefined . Tan pronto como se reciban las coordenadas, el componente se volver谩 a dibujar y los veremos en la pantalla.


Implementaci贸n de usePosition()


Nuestro gancho usePosition() es una funci贸n JavaScript normal que se ve as铆:


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

Usaremos los ganchos useState () para el almacenamiento interno de coordenadas y useEffect () para suscribir y cancelar la suscripci贸n de coordenadas de seguimiento. Para hacer esto, debemos importarlos.


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

Crearemos variables de estado en las que almacenaremos coordenadas o un error en la obtenci贸n de coordenadas (por ejemplo, si el usuario se niega a compartir su ubicaci贸n).


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

Tambi茅n en esta etapa podemos devolver las variables que se esperan del gancho. Hasta ahora, no hay nada 煤til en estas variables, pero lo arreglaremos pronto.


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

Y ahora el momento clave de implementaci贸n es obtener coordenadas.


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

En el useEffect() , primero verificamos si el navegador admite la funcionalidad de detecci贸n de coordenadas. Si la funcionalidad no es compatible, salimos del gancho con un error. De lo contrario, nos suscribimos a cambiar la geolocalizaci贸n del navegador utilizando las onError() onChange onChange() y onError() (agregaremos su c贸digo a continuaci贸n). Tenga en cuenta que desde el useEffect() , devolvemos una funci贸n an贸nima que se ejecutar谩 si el componente se elimina de la pantalla. En esta funci贸n an贸nima, nos damos de baja de la vigilancia para no obstruir la memoria. Por lo tanto, toda la l贸gica de suscribirse y darse de baja del seguimiento est谩 en un gancho usePosition() .


Agreguemos las devoluciones de llamada faltantes:


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

El gancho usePosition() est谩 listo para usar.


Al final


Puede encontrar una demostraci贸n del gancho y su implementaci贸n m谩s detallada con la capacidad de establecer par谩metros de seguimiento en GitHub .


Espero que este art铆culo te haya sido 煤til. Codificaci贸n exitosa!

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


All Articles