例えば、名前が並んでいて「並び替え」ボタンを押すと順番が変わる機能を作るとき、これまでは次のように実装してた。
ローカル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が実行されてしまっていたこと。
以上