إنشاء ربط Reactive UsePosition () للحصول على إحداثيات المستعرض وتتبعها

صورة


إذا لفترة وجيزة


في هذه المقالة ، سنقوم بإنشاء ربط تفاعلي usePosition() لتتبع تحديد الموقع الجغرافي للمتصفح. تحت الغطاء ، سوف يستخدم هذا الخطاف getCurrentPosition() و watchPosition() في navigator.geolocation كائن المستعرض الأصلي. لقد نشرت النسخة النهائية من الخطاف على جيثب و NPM .


لماذا إنشاء ربط usePosition() حيث المبدأ


تتمثل إحدى المزايا المهمة للخطافات في React في القدرة على عزل أجزاء التعليمات البرمجية المرتبطة منطقياً في مكان واحد (في الخطاف) ، مع تجنب الحاجة إلى مزج أجزاء التعليمات البرمجية غير المرتبطة منطقياً ، على سبيل المثال ، في طريقة componentDidMount() للمكون.


لنفترض أننا نريد الحصول على إحداثيات المستعرض ( latitude longitude ) وبعد تلقي الإحداثيات ، طلب تنبؤ بالطقس أو درجة الحرارة الحالية في هذه المنطقة من خدمة تابعة لجهة خارجية. غالبًا ما يتم وضع رمز هاتين الوظيفتين (الحصول على إحداثيات وطلب درجة حرارة) في React داخل طريقة componentDidMount() واحد. في هذه الحالة ، عادةً ما يتم "تنظيف" طريقة componentWillUnmount () بمفردها ، وتستدعي طريقة clearWatch () لإيقاف مراقبة موقع المستعرض. مثل هذا النهج يزيد من حجم الطرق ، ويقسم مقاطع الكود المرتبطة منطقيا إلى أجزاء (الاشتراك بشكل منفصل وإلغاء الاشتراك من مراقبة موقع المستعرض) ، ويجمع بين الأجزاء ذات الارتباط المنطقي ضعيفة من الكود في طريقة واحدة (الحصول على الإحداثيات ودرجة الحرارة). قراءة التعليمات البرمجية صعبة ، وكذلك تصحيح الأخطاء والدعم.


بعد ذلك ، سنحاول نقل الوظيفة المرتبطة بالحصول على إحداثيات المستعرض في usePosition() منفصل لتجنب الصعوبات المذكورة أعلاه.


كيف usePosition() ربط usePosition()


دعنا نذهب "من العكس" وقبل تنفيذ الخطاف نفسه ، دعونا نخطط لكيفية استخدامه. سيساعدنا ذلك في تحديد واجهة الخطاف (ما ستقبله وما ستعوده).


أبسط مثال على الحصول على الإحداثيات وعرضها على الشاشة قد يبدو كما يلي:


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

خط واحد فقط مع usePosition() ويمكننا العمل مع latitude longitude . لم نستخدم حتى useState() أو useEffect() بشكل صريح هنا. يتم تضمين اشتراك في تتبع الإحداثيات ، وكذلك حذف مشترك ، في usePosition() واحد usePosition() . علاوة على ذلك ، فإن سحر إعادة رسم مكونات React سيفعل كل شيء لنا. في البداية ، ستكون الإحداثيات null أو undefined . بمجرد استلام الإحداثيات ، سيتم إعادة رسم المكون وسنراهم على الشاشة.


usePosition() تنفيذ usePosition()


usePosition() هو وظيفة JavaScript عادية تبدو كما يلي:


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

سنستخدم خطاطيف useState () للتخزين الداخلي للإحداثيات و useEffect () للاشتراك وإلغاء الاشتراك من إحداثيات التتبع. للقيام بذلك ، يجب علينا استيرادها.


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

سننشئ متغيرات الحالة التي سنخزن بها إحداثيات أو خطأ في الحصول على إحداثيات (على سبيل المثال ، إذا رفض المستخدم مشاركة موقعه).


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

أيضًا في هذه المرحلة ، يمكننا إرجاع المتغيرات المتوقعة من الخطاف. لا يوجد شيء مفيد حتى الآن في هذه المتغيرات ، لكننا سنصلحها قريبًا.


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

والآن لحظة التنفيذ الرئيسية هي الحصول على إحداثيات.


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

في ربط useEffect() ، نتحقق أولاً لمعرفة ما إذا كان المستعرض يدعم وظيفة الكشف عن الإحداثيات. إذا كانت الوظيفة غير مدعومة ، فسنخرج الخطاف مع وجود خطأ. وإلا ، فإننا نشترك في تغيير الموقع الجغرافي للمتصفح باستخدام عمليات onError() onChange onChange() و onError() (سنقوم بإضافة الكود أدناه). لاحظ أنه من خلال استخدام useEffect() ، نرجع وظيفة مجهولة المصدر سيتم تنفيذها إذا تمت إزالة المكون من الشاشة. في هذه الوظيفة المجهولة ، نقوم بإلغاء الاشتراك في المراقبة حتى لا تسد الذاكرة. وبالتالي ، فإن المنطق الكامل للاشتراك usePosition() الاشتراك من التعقب هو usePosition() واحد usePosition() .


دعنا نضيف عمليات الاسترجاعات المفقودة:


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

ربط usePosition() جاهز للاستخدام.


في النهاية


يمكنك العثور على عرض توضيحي للخطاف وتنفيذه أكثر تفصيلًا مع إمكانية تعيين معلمات التتبع على GitHub .


آمل أن يكون هذا المقال مفيدًا لك. الترميز الناجح!

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


All Articles