برنامه نویسی

React – یک قلاب سفارشی برای مدیریت رویدادهای آنلاین و آفلاین با استفاده از AbortController و addEventListener ایجاد کنید.

استفاده از AbortController در مقابل removeEventListener

با استفاده از AbortController

import { useEffect } from "react"

export function useOnlineStatus(onlineCallback: () => void, offlineCallback: () => void) {
  useEffect(() => {
    const controller = new AbortController()
    window.addEventListener("online", onlineCallback, { signal: controller.signal })
    window.addEventListener("offline", offlineCallback, { signal: controller.signal })

    return () => {
      controller.abort()
    }
  }, [onlineCallback, offlineCallback])
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در مقابل

با استفاده از removeEventListener

import { useEffect } from 'react';

export function useOnlineStatus(
  onlineCallback: () => void,
  offlineCallback: () => void
) {
  useEffect(() => {
    window.addEventListener('online', onlineCallback);
    window.addEventListener('offline', offlineCallback);

    return () => {
      window.removeEventListener('online', onlineCallback);
      window.removeEventListener('offline', offlineCallback);
    };
  }, [onlineCallback, offlineCallback]);
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خوانایی

عملکرد پاکسازی (هر رندر مجدد و باز کردن) از useEffect به سادگی می تواند تماس بگیرد controller.abort()

...

return () => {
    controller.abort()
}

...
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مشکل: وضعیت آنلاین نادرست ارائه شده است

به عنوان مثال،

از متغیر بازده توسط هوک استفاده کنید useOnlineStatus در برنامه کامپوننت

useOnlineStatus.ts

import { useEffect } from "react"

export function useOnlineStatus(onlineCallback: () => void, offlineCallback: () => void) {
  useEffect(() => {
    const controller = new AbortController()
    window.addEventListener("online", onlineCallback, { signal: controller.signal })
    window.addEventListener("offline", offlineCallback, { signal: controller.signal })

    return () => {
      controller.abort()
    }
  }, [onlineCallback, offlineCallback])

  // return the window online status
  return navigator.onLine;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

App.tsx

import React, {useCallback} from 'react';
import { useOnlineStatus } from './hook';

export function App(props) {
  const handleOnline = useCallback(() => {
    console.log('online');
  }, []);
  const handleOffline = useCallback(() => {
    console.log('offline');
  }, []);
  const isOnline = useOnlineStatus(handleOnline, handleOffline);
  return (
    

Start editing to see some magic happen!

Online status: {isOnline.toString()}

); }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با این حال، هنگام جابه‌جایی بین «آفلاین» و «بدون throttling» در برگه «شبکه» ابزار توسعه‌دهنده Chrome، برنامه مؤلفه وضعیت آنلاین صحیح را نشان نمی‌دهد. isOnline.

ببینید که ارزش isOnline وقتی وضعیت اتصال آنلاین است نادرست است:

توضیحات تصویر

علت ریشه ای

زیرا تنها زمانی که کامپوننت App رندر می شود، مقدار آن را برمی گرداند navigator.onLine هنگام فراخوانی قلاب useOnlineStatus به متغیر اختصاص داده خواهد شد isOnline. با این حال، هنگامی که وضعیت آنلاین تغییر می کند، کامپوننت App دوباره رندر نمی شود، که وضعیت قدیمی را نشان می دهد isOnline به جای جریان navigator.onLine مقدار در پنجره

راه حل

به روز رسانی useOnlineStatus قلاب برای بازگشت متغیر حالت به جای navigator.onLine.

زمانی که online رویداد به هدف (پنجره)، توابع پاسخ به تماس تحویل داده می شود onlineCallback و set به ترتیب برای انجام وظایف و به روز رسانی متغیرهای حالت فراخوانی می شوند. زمانی که offline رویداد به هدف (پنجره) تحویل داده می شود، اصل کار مشابه است.

حالت varialbe را اعلام کنید isOnline

const [isOnline, setIsOnline] = useState(true);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کدهای کامل

import { useEffect, useState, useCallback } from 'react';

export function useOnlineStatus(
  onlineCallback: () => void,
  offlineCallback: () => void
) {
  const [isOnline, setIsOnline] = useState(true);
  const handleOnline = useCallback(() => {
    onlineCallback();
    setIsOnline(true);
  }, []);
  const handleOffline = useCallback(() => {
    offlineCallback();
    setIsOnline(false);
  }, []);

  useEffect(() => {
    const controller = new AbortController();
    window.addEventListener('online', handleOnline, {
      signal: controller.signal,
    });
    window.addEventListener('offline', handleOffline, {
      signal: controller.signal,
    });

    return () => {
      controller.abort();
    };
  }, [onlineCallback, offlineCallback]);
  return isOnline;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به این ترتیب، هنگامی که وضعیت آنلاین/آفلاین تغییر می کند، برنامه جزء با استفاده از useOnlineStatus هوک مجددا رندر می شود و وضعیت صحیح آنلاین را نمایش می دهد.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا