KASHIMURA Blog

Webサービス開発のこと、個人的なことを書いているブログ

最近 React × Apolloで余計なrefetchを呼び出していたことに気がついた

例えば、名前が並んでいて「並び替え」ボタンを押すと順番が変わる機能を作るとき、これまでは次のように実装してた。
ローカルstateに条件を保持して、useEffect()がstateの変更をキャッチしてrefetch()を実行させる。こんな実装。
ただ、3年もこの実装していて最近気がついたけど、このuseEffectは不要だった...

以下に具体的な説明。

👇 ダメなコード(実装は適当)

import React, { FC, useState, useEffect } from "react";
import { useUsersQuery } from "~/graphql/generated/schema";

export const Users: FC = () => {
  const [order, setOrder] = useState<"asc" | "desc">("asc");
  const { data, refetch } = useUsersQuery({ variables: { order } });

  # ここがいらない...
  useEffect(() => {
    refetch();
  }, [order, refetch]);

  return (
    <div>
      <button type="button" onClick={() => setOrder("desc")}>並び替え</button>
      {data.users.edges.map((v) => (
        <div>{v.node.name}</div>
      ))}
    </div>
  );
};

※ useUsersQuery()はgraphql-codegenが自動生成したApollo.useQueryの結果を返す関数

上記のコードは、並び順をローカルstateのorderが持っていてQueryの条件に指定している。

orderが変わったことをuseEffect()がキャッチして、Queryを別の条件で再度実行するようになってる。

ただ、このuseEffect()は無くても問題なかった...

理由は、Queryのvaliablesにorderを指定しているので、orderが変更されたらよしなにQueryが実行されるようになってるから。

しかも、このrefetch呼ぶ実装の良くない点は、本来キャッシュが効く条件の場合でもQueryが実行されてしまっていたこと。

以上