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
هوک مجددا رندر می شود و وضعیت صحیح آنلاین را نمایش می دهد.