Created
March 27, 2021 21:22
-
-
Save patrickcze/b0701f4aa9dbaa7e815a0af62c41541e to your computer and use it in GitHub Desktop.
A upgraded version of our hook.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState, useEffect, useContext } from "react"; | |
const PING_RESOURCE = "/ping.txt"; | |
const TIMEOUT_TIME_MS = 3000; | |
const onlinePollingInterval = 10000; | |
const timeout = (time: number, promise: Promise) => { | |
return new Promise(function(resolve, reject) { | |
setTimeout(() => { | |
reject(new Error("Request timed out.")); | |
}, time); | |
promise.then(resolve, reject); | |
}); | |
}; | |
const checkOnlineStatus = async () => { | |
const controller = new AbortController(); | |
const { signal } = controller; | |
// If the browser has no network connection return offline | |
if (!navigator.onLine) return navigator.onLine; | |
// | |
try { | |
await timeout( | |
TIMEOUT_TIME_MS, | |
fetch(PING_RESOURCE, { | |
method: "GET", | |
signal | |
}) | |
); | |
return true; | |
} catch (error) { | |
// Error Log | |
console.error(error); | |
// This can be because of request timed out | |
// so we abort the request for any case | |
controller.abort(); | |
} | |
return false; | |
}; | |
const OnlineStatusContext = React.createContext(true); | |
export const OnlineStatusProvider: React.FC = ({ children }) => { | |
const [onlineStatus, setOnlineStatus] = useState<boolean>(true); | |
const checkStatus = async () => { | |
const online = await checkOnlineStatus(); | |
setOnlineStatus(online); | |
}; | |
useEffect(() => { | |
window.addEventListener("offline", () => { | |
setOnlineStatus(false); | |
}); | |
// Add polling incase of slow connection | |
const id = setInterval(() => { | |
checkStatus(); | |
}, onlinePollingInterval); | |
return () => { | |
window.removeEventListener("offline", () => { | |
setOnlineStatus(false); | |
}); | |
clearInterval(id); | |
}; | |
}, []); | |
return ( | |
<OnlineStatusContext.Provider value={onlineStatus}> | |
{children} | |
</OnlineStatusContext.Provider> | |
); | |
}; | |
export const useOnlineStatus = () => { | |
const store = useContext(OnlineStatusContext); | |
return store; | |
}; | |
export default useOnlineStatus; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@AkshayHere It comes out of the box, so to speak. See https://developer.mozilla.org/en-US/docs/Web/API/AbortController