Context
We are currently developing a React Native iOS app with a Graphql back-end. Within this app we would like to show the user a modal when there is no internet connection or when the API is down.
Since we are using Apollo and graphql-code-generator
, we have a generated hook in the component that retrieves the data. We show the modal when the hook returns a network error. If a network error has been found, the refetch
method from the hook is used to poll and see whether the network or API is back up.
The Problem
This unfortunately does not seem to work, calls to the refetch
method after the network has been reestablished do not result in requests. The refetch
method also throws a network error.
Code
function useConnectionStatusPolling() { // 'useData' is a custom wrapper around the generated hook, that maps and deserialises fields. const { loading, refetch, error } = useData(); // While refreshing, error.networkError is reset.But we would like // to keep the error status around until the request works again. // // For that, we keep the error in the mutable reference, and update it // only when the status it not loading. For loading, keep the // previous value. const networkError = useRef(false); if (!loading) { networkError.current = !!error?.networkError; } // Polling is done manually via useInterval because the builtin polling stops // if a network error is thrown which we want to ignore in our case. useInterval(refetch, networkError.current ? 5000 : "pause"); return networkError.current;}
/** * Executes a callback at each interval. * https://overreacted.io/making-setinterval-declarative-with-react-hooks/ * @param callback Method to execute after each delay. * @param delay Time in miliseconds. */export function useInterval(callback: () => void, delay: number | "pause") { const savedCallback = useRef<() => void>(); // Remember the latest callback. useEffect(() => { savedCallback.current = callback; }, [callback]); // Set up the interval. useEffect(() => { function tick() { savedCallback.current?.(); } if (delay !== "pause") { const id = setInterval(tick, delay); return () => clearInterval(id); } }, [delay]);}
Research & Attempts
We did find out that the error is not cleared as specified in this article. So this hook won't will keep showing the no internet modal and making requests. However this problem still persists after this change, the refetch method just does not make a request to the API. We also tried clearing the cache, but to no avail unfortunately. So I am not really sure what to try at the moment in order to make this work, any advice would be greatly appreciated!