ウェブサイト検索

typescript - ネットワークエラー後、Apolloの再取得がリクエストを行わない


コンテキスト

私たちは現在、Graphqlバックエンドを持つReact Native iOSアプリを開発しています。このアプリ内では、インターネット接続がない場合やAPIがダウンしている場合に、ユーザーにモーダルを表示したいと考えています。

私たちはApolloとgraphql-code-generatorを使用しているので、データを取得するコンポーネント内に生成されたフックがあります。フックがネットワークエラーを返すとモーダルを表示します。ネットワークエラーが検出された場合、フックからのrefetchメソッドを使用して、ネットワークやAPIが復旧しているかをポーリングします。

問題

残念ながら、これはうまくいかないようです。ネットワークが再確立された後にrefetchメソッドを呼び出しても、リクエストは発生しません。refetchメソッドはネットワークエラーもスローします。

コード

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]);
}

研究と試み

私たちは、このエラーがこの記事に記載されている通りにはクリアされないことを確認しました。したがって、このフックはインターネットがない際のモーダルを表示し続け、リクエストを送信し続けることになります。しかし、この変更後も問題は依然として残っており、refetch メソッドは API へのリクエストを行いませんでした。キャッシュをクリアすることも試しましたが、残念ながら効果はありませんでした。ですので、現時点では何を試せばこれが動作するのか私にはよくわかりません。どんなアドバイスでも大変ありがたく思います!

編集

問題をより簡単な方法で再現できる小さな Expo スナック(コードスニペット)を作成しました。ここでは問題は発生しません!それでも、なぜこの問題が私たちのアプリで続いているのかは全くわからないので、どんなフィードバックも歓迎です!

おやつ