Estoy lidiando con un problema en el que una consulta dentro de un gancho useQuery Apollo Client se vuelve a ejecutar innecesariamente cada vez que se llama al router.push de router.push ( documentos aquí ).
El código abreviado es:
const Parent = () => { useQuery(QUERY_HERE, { onCompleted: () => { console.log("just completed apollo query"); } }); return <Child />; } const Child = () => { const router = useRouter(); const currentArg = router.query?.currentArg; return ( <div> <button onClick={() => { if (currentArg === "on") { router.push("/?currentArg=off"); } else { router.push("/?currentArg=on"); } }} > Click me! </button> </div> ); };Puede ver una reproducción en CodeSandbox aquí.
Mi expectativa es que cada vez que se haga clic en el botón (y, por lo tanto, se llame router.push ), la consulta no se debe volver a ejecutar. Sin embargo, se vuelve a ejecutar cada vez que se hace clic en el botón. Esto es sorprendente porque entiendo que una consulta de Apollo solo debe volver a ejecutarse cuando cambia una de sus variables.
¿Alguien sabe de una manera de asegurarse de que la consulta de Apollo no se vuelva a ejecutar?
Next.js vuelve a representar las páginas cuando se produce la navegación y, en su ejemplo, recrea Apollo Client cada vez que sucede. Luego, su componente useQuery se procesa nuevamente, verifica si el caché contiene datos para la consulta dada (no lo hace, ya que el nuevo cliente está vacío) y envía la consulta nuevamente.
Para solucionar esto, cree su ApolloClient en el ámbito global. De esta forma, se mantendrá estable y se podrá reutilizar entre múltiples consultas y renderizaciones.