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

Next.js使用useQuery报watchQuery未定义错误,求助排查依赖问题

解决Next.js中useQuery报错"cannot read properties of undefined (reading 'watchQuery')"

我有一个Next.js应用,调用useQuery时触发错误:cannot read properties of undefined (reading 'watchQuery') at useQuery。之前为了解决Hook渲染错误,多次调整next和apollo-client的版本,怀疑是依赖或配置问题,相关文件如下:

package.json

{
  "dependencies": {
    "@apollo/client": "3.6.2",
    "@apollo/link-error": "^2.0.0-beta.3",
    "@apollo/react-ssr": "^4.0.0",
    "@keystone-6/document-renderer": "^1.1.2",
    "@sentry/nextjs": "^7.52.1",
    "@stripe/react-stripe-js": "^1.1.2",
    "@stripe/stripe-js": "^1.11.0",
    "apollo-upload-client": "^14.1.3",
    "babel-core": "^7.0.0-bridge.0",
    "babel-plugin-macros": "^3.1.0",
    "babel-plugin-styled-components": "^2.1.1",
    "date-fns": "^2.16.1",
    "downshift": "^6.0.12",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.5",
    "graphql": "15.8.0",
    "graphql-tag": "^2.11.0",
    "graphql-upload": "^11.0.0",
    "lodash.debounce": "^4.0.8",
    "next": "^12.2.2",
    "next-with-apollo": "^5.1.1",
    "nprogress": "^0.2.0",
    "prop-types": "^15.7.2",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-is": "^17.0.2",
    "react-transition-group": "^4.4.1",
    "styled-components": "^5.2.1",
    "vercel": "^29.3.4",
    "waait": "^1.0.5"
  },
  "devDependencies": {
    "@apollo/react-testing": "^4.0.0",
    "@babel/core": "^7.12.10",
    "@babel/preset-env": "^7.12.11",
    "@testing-library/jest-dom": "^5.11.8",
    "@testing-library/react": "^11.2.3",
    "@testing-library/user-event": "^12.6.0",
    "babel-eslint": "^10.1.0",
    "babel-jest": "^26.6.3",
    "babel-plugin-styled-components": "^2.1.1",
    "casual": "^1.6.2",
    "eslint": "^7.17.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-config-prettier": "^7.1.0",
    "eslint-config-wesbos": "^1.0.1",
    "eslint-plugin-html": "^6.1.1",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-prettier": "^3.3.1",
    "eslint-plugin-react": "^7.22.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "jest": "^26.6.3",
    "prettier": "^2.2.1",
    "react-test-renderer": "^17.0.1"
  },
  "engines": {
    "node": "16.x"
  },
  "//": "This is our babel config, I prefer this over a .babelrc file",
  "babel": {
    "env": {
      "development": {
        "presets": [
          "next/babel"
        ],
        "plugins": [
          [
            "babel-plugin-styled-components",
            "macros",
            {
              "ssr": true,
              "displayName": true
            }
          ]
        ]
      },
      "production": {
        "presets": [
          "next/babel"
        ],
        "plugins": [
          [
            "babel-plugin-styled-components",
            "macros",
            {
              "ssr": true,
              "displayName": true
            }
          ]
        ]
      },
      "test": {
        "presets": [
          [
            "next/babel",
            {
              "preset-env": {
                "modules": "commonjs"
              }
            }
          ]
        ],
        "plugins": [
          [
            "babel-plugin-styled-components",
            {
              "ssr": true,
              "displayName": true
            }
          ]
        ]
      }
    }
  }
}

createClient代码(withData.js)

import { ApolloClient, ApolloLink, InMemoryCache } from "@apollo/client";
import { onError } from "@apollo/link-error";
import { createUploadLink } from "apollo-upload-client";
import withApollo from "next-with-apollo";
import { prodEndpoint, cors } from "../config";

function createClient({ headers, initialState }) {
  return new ApolloClient({
    link: ApolloLink.from([
      onError(({ graphQLErrors, networkError }) => {
        if (graphQLErrors)
          graphQLErrors.forEach(({ message, locations, path }) =>
            console.log(
              `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
            )
          );
        if (networkError)
          console.log(
            `[Network error]: ${networkError}. Backend is unreachable. Is it running?`
          );
      }),
      createUploadLink({
        uri: prodEndpoint,
        cors,
        fetchOptions: {
          credentials: "include",
        },
        headers,
      }),
    ]),
    cache: new InMemoryCache().restore(initialState || {}),
  });
}

export default withApollo(createClient);

_app.js代码

import { ApolloProvider } from "@apollo/client";
import NProgress from "nprogress";
import Router from "next/router";
import Page from "../components/Page";
import "../components/styles/nprogress.css";
import apolloClient from "../lib/withData";

Router.events.on("routeChangeStart", () => NProgress.start());
Router.events.on("routeChangeComplete", () => NProgress.done());
Router.events.on("routeChangeError", () => NProgress.done());

function MyApp({ Component, pageProps }) {
  // const router = useRouter();
  return (
    <ApolloProvider client={apolloClient}>
      <Page>
        <Component {...pageProps} />
      </Page>
    </ApolloProvider>
  );
}

MyApp.getInitialProps = async function ({ Component, ctx }) {
  let pageProps = {};
  console.log(pageProps);
  if (Component.getInitialProps) {
    console.log(`Paging all props ${pageProps}`);
    pageProps = await Component.getInitialProps(ctx);
  }
  pageProps.query = ctx.query;
  return { pageProps };
};

export default MyApp;

问题分析

  1. 核心配置错误:_app.js中错误地将next-with-apollo返回的高阶组件直接传给ApolloProvider的client属性。next-with-apollo的作用是通过高阶组件为应用注入ApolloClient实例,而非直接导出client对象,导致ApolloProvider未拿到有效的client实例,useQuery无法找到client从而报错。
  2. 冗余/冲突依赖:@apollo/react-ssr是Apollo Client v2的SSR包,而当前使用的@apollo/client@3.6.2已经内置了SSR功能,两者共存会导致版本冲突;@apollo/react-testing同理,v3版本应使用@apollo/client/testing。

解决方案

步骤1:修正_app.js的ApolloProvider使用方式

next-with-apollo返回的是高阶组件,需要用它包裹你的MyApp组件,而非直接引用apolloClient作为client参数。修改后的_app.js如下:

import { ApolloProvider } from "@apollo/client";
import NProgress from "nprogress";
import Router from "next/router";
import Page from "../components/Page";
import "../components/styles/nprogress.css";
import withApollo from "../lib/withData";

Router.events.on("routeChangeStart", () => NProgress.start());
Router.events.on("routeChangeComplete", () => NProgress.done());
Router.events.on("routeChangeError", () => NProgress.done());

function MyApp({ Component, pageProps, apolloClient }) {
  return (
    <ApolloProvider client={apolloClient}>
      <Page>
        <Component {...pageProps} />
      </Page>
    </ApolloProvider>
  );
}

MyApp.getInitialProps = async function ({ Component, ctx }) {
  let pageProps = {};
  if (Component.getInitialProps) {
    pageProps = await Component.getInitialProps(ctx);
  }
  pageProps.query = ctx.query;
  return { pageProps };
};

// 使用next-with-apollo高阶组件包裹MyApp
export default withApollo(MyApp);

步骤2:清理冲突依赖

更新package.json,移除冗余的旧版Apollo依赖,调整后相关依赖如下:

"dependencies": {
  "@apollo/client": "3.6.2",
  "@apollo/client/link/error": "^3.6.2", // 替换@apollo/link-error beta版
  "@keystone-6/document-renderer": "^1.1.2",
  "@sentry/nextjs": "^7.52.1",
  "@stripe/react-stripe-js": "^1.1.2",
  "@stripe/stripe-js": "^1.11.0",
  "apollo-upload-client": "^14.1.3",
  "babel-core": "^7.0.0-bridge.0",
  "babel-plugin-macros": "^3.1.0",
  "babel-plugin-styled-components": "^2.1.1",
  "date-fns": "^2.16.1",
  "downshift": "^6.0.12",
  "enzyme": "^3.11.0",
  "enzyme-adapter-react-16": "^1.15.5",
  "graphql": "15.8.0",
  "graphql-tag": "^2.11.0",
  "graphql-upload": "^11.0.0",
  "lodash.debounce": "^4.0.8",
  "next": "^12.2.2",
  "next-with-apollo": "^5.1.1",
  "nprogress": "^0.2.0",
  "prop-types": "^15.7.2",
  "react": "^17.0.2",
  "react-dom": "^17.0.2",
  "react-is": "^17.0.2",
  "react-transition-group": "^4.4.1",
  "styled-components": "^5.2.1",
  "vercel": "^29.3.4",
  "waait": "^1.0.5"
},
"devDependencies": {
  "@apollo/client/testing": "^3.6.2", // 替换@apollo/react-testing
  "@babel/core": "^7.12.10",
  "@babel/preset-env": "^7.12.11",
  "@testing-library/jest-dom": "^5.11.8",
  "@testing-library/react": "^11.2.3",
  "@testing-library/user-event": "^12.6.0",
  "babel-eslint": "^10.1.0",
  "babel-jest": "^26.6.3",
  "babel-plugin-styled-components": "^2.1.1",
  "casual": "^1.6.2",
  "eslint": "^7.17.0",
  "eslint-config-airbnb": "^18.2.1",
  "eslint-config-prettier": "^7.1.0",
  "eslint-config-wesbos": "^1.0.1",
  "eslint-plugin-html": "^6.1.1",
  "eslint-plugin-import": "^2.22.1",
  "eslint-plugin-jsx-a11y": "^6.4.1",
  "eslint-plugin-prettier": "^3.3.1",
  "eslint-plugin-react": "^7.22.0",
  "eslint-plugin-react-hooks": "^4.2.0",
  "jest": "^26.6.3",
  "prettier": "^2.2.1",
  "react-test-renderer": "^17.0.1"
}

步骤3:重新安装依赖

执行以下命令清理并重新安装依赖:

rm -rf node_modules package-lock.json yarn.lock
npm install # 或 yarn install

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:24:55