You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js的useEffect中实现Apollo useQuery并更新页面数据?

问题翻译

我正在使用Apollo获取数据,希望页面重新渲染时能展示新数据,请问如何在Next.js的useEffect中实现Apollo useQuery?

解决方案

首先明确:React Hooks(包括useQuery)不能直接在useEffect内部调用——Hooks必须遵循调用规则,只能在组件顶层或自定义Hook中执行。你不需要把useQuery放进useEffect,而是利用Apollo内置的刷新机制来实现需求,以下是几种可行方案:

方案1:用refetch手动触发数据刷新

通过解构useQuery返回的refetch方法,配合useEffect监听依赖变化,在需要时重新获取数据(比如用户创建成功后)。

修改后的代码示例:

import { GET_ALL_USERS } from "@/graphql/queries"
import { useQuery } from "@apollo/client"
import { useEffect, useState } from "react";

export default function Home() {
  // 解构出refetch方法
  const { data, loading, refetch } = useQuery(GET_ALL_USERS);
  // 用状态标记是否需要刷新数据
  const [shouldRefetch, setShouldRefetch] = useState(false);

  // 监听状态变化,触发数据刷新
  useEffect(() => {
    if (shouldRefetch) {
      refetch();
      setShouldRefetch(false); // 重置状态
    }
  }, [shouldRefetch, refetch]);

  // 传递给CreateUser组件的回调:创建成功后标记需要刷新
  const handleUserCreated = () => {
    setShouldRefetch(true);
  };

  return (
    <>
      <CreateUser onUserCreated={handleUserCreated} />
      {loading ?
        <span>加载数据中,请稍候...</span>
        :
        data?.getAllUsers.map((user: any, index: any) => {
          // 优先用user.id作为key,避免index带来的问题
          return <div key={user.id || index}>{user.name} {user.username}</div>
        })
      }
    </>
  )
}

方案2:设置pollInterval自动轮询

如果需要定期自动刷新数据,给useQuery添加pollInterval参数(单位:毫秒),即可实现定时重新获取数据:

const { data, loading } = useQuery(GET_ALL_USERS, {
  pollInterval: 5000, // 每5秒自动刷新一次数据
});

方案3:更新Apollo缓存自动触发重渲染

当通过useMutation创建用户时,在mutation的update函数中直接更新缓存,useQuery会自动检测到缓存变化,触发组件重渲染,无需手动发起请求。

示例(CreateUser组件内部的mutation逻辑):

import { CREATE_USER } from "@/graphql/mutations";
import { useMutation } from "@apollo/client";
import { GET_ALL_USERS } from "@/graphql/queries";

function CreateUser() {
  const [createUser] = useMutation(CREATE_USER, {
    update(cache, { data: { createUser } }) {
      // 读取当前缓存中的用户列表
      const { getAllUsers } = cache.readQuery({ query: GET_ALL_USERS });
      // 将新用户写入缓存,触发useQuery更新
      cache.writeQuery({
        query: GET_ALL_USERS,
        data: { getAllUsers: [...getAllUsers, createUser] },
      });
    },
  });

  // 创建用户的表单逻辑...
}

关键提示

  • 不要尝试在useEffect内部调用useQuery,这违反React Hooks规则会导致报错。
  • 优先选择缓存更新的方式,性能更优;若必须重新获取数据,使用refetch配合状态监听的方案。

内容的提问来源于stack exchange,提问作者erwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 04:57:17