Created
February 23, 2025 12:35
-
-
Save RodolfoSilva/5506d5e9720aad9868f904f9817047b8 to your computer and use it in GitHub Desktop.
Check if internet is Reachable
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 {useEffect} from 'react'; | |
import {Text} from 'react-native'; | |
import {useNetworkState} from 'expo-network'; | |
import useIsInternetReachable from './useIsInternetReachable'; | |
import { usePrevious } from "@uidotdev/usehooks"; | |
export default function OnlineBadge() { | |
const [isOnline, {check}] = useIsInternetReachable(); | |
// Optional | |
const networkState = useNetworkState(); | |
const previousConnected = usePrevious(networkState.isConnected); | |
useEffect(() => { | |
if (networkState.isConnected !== previousConnected) { | |
setTimeout(check, 500); | |
} | |
}, [check, networkState.isConnected, previousConnected]); | |
return <Text>{isOnline ? 'Online' : 'Offline'}</Text>; | |
} |
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 {useCallback, useEffect, useRef, useState} from 'react'; | |
async function checkInternet(endpoints: string[], timeout: number) { | |
try { | |
return await Promise.any( | |
endpoints.map(async url => { | |
// The request will fail if the URL is not reachable, or due a timeout | |
const controller = new AbortController(); | |
const abort = setTimeout(() => controller.abort(), timeout); | |
await fetch(url, { | |
method: 'HEAD', | |
signal: controller.signal, | |
}); | |
clearTimeout(abort); | |
return true; | |
}), | |
); | |
} catch { | |
return false; | |
} | |
} | |
const urisToCheck = [ | |
'https://one.one.one.one', | |
'https://icanhazip.com/', | |
'https://jsonplaceholder.typicode.com/todos/1', | |
'https://reqres.in/api/users/1', | |
'https://clients1.google.com/generate_204', | |
]; | |
type Options = { | |
initialValue?: boolean; | |
enabled?: boolean; | |
checkInterval?: number; | |
checkTimeout?: number; | |
}; | |
export default function useIsInternetReachable(options: Options = {}) { | |
const { | |
enabled = true, | |
initialValue = true, | |
checkInterval = 10000, | |
checkTimeout = 3000, | |
} = options; | |
const [reachable, setReachable] = useState(initialValue); | |
const mountedRef = useRef(true); | |
const runningRef = useRef(false); | |
useEffect(() => { | |
return () => { | |
mountedRef.current = false; | |
}; | |
}, []); | |
const check = useCallback(async () => { | |
if (runningRef.current) return; | |
runningRef.current = true; | |
const online = await checkInternet(urisToCheck, checkTimeout); | |
runningRef.current = false; | |
if (!mountedRef.current) return; | |
setReachable(online); | |
}, [checkTimeout]); | |
useEffect(() => { | |
if (!enabled || checkInterval <= 0) return; | |
let timeoutId: ReturnType<typeof setTimeout>; | |
const verify = async () => { | |
await check(); | |
timeoutId = setTimeout(() => verify(), checkInterval); | |
}; | |
verify(); | |
return () => { | |
clearTimeout(timeoutId); | |
}; | |
}, [enabled, checkInterval, check]); | |
return [reachable, {check}] as const; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment