Skip to content

Instantly share code, notes, and snippets.

@RodolfoSilva
Created February 23, 2025 12:35
Show Gist options
  • Save RodolfoSilva/5506d5e9720aad9868f904f9817047b8 to your computer and use it in GitHub Desktop.
Save RodolfoSilva/5506d5e9720aad9868f904f9817047b8 to your computer and use it in GitHub Desktop.
Check if internet is Reachable
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>;
}
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