apollo-server-express下useQuery报bind undefined错误排查修复
基础疑问解答
Express原生CRUD能力与Apollo GraphQL能力完全可以共存使用,不存在二选一的限制。二者路由规则完全独立:常规REST接口走自定义的业务路径,GraphQL请求默认由apollo-server-express挂载的/graphql路径中间件处理,互不干扰。
报错原因
你遇到的报错Cannot read properties of undefined (reading 'bind')(中文含义:无法读取undefined对象的'bind'属性),核心原因是客户端Apollo依赖版本不兼容:
- 你同时使用了已废弃的旧版包
apollo-boost初始化客户端,又从新版@apollo/client导入useQuery、InMemoryCache、ApolloProvider等API。 apollo-boost是Apollo Client 2.x时代的兼容预设包,内置了独立的缓存、请求链路实现,和3.x版本的React Hooks(比如useQuery)存在API断层。这也是mutation、常规CRUD请求能正常运行,只有useQuery失效的原因:mutation是用户操作触发的主动调用,query在hooks层会提前绑定缓存、订阅相关方法,新旧包的API不匹配会直接导致绑定阶段报错。- 你的typeDefs和resolver在Apollo Studio中可正常运行,已经排除服务端逻辑问题。
修复步骤
- 第一步:卸载废弃依赖
执行命令移除不再维护的apollo-boost包,所有Apollo Client相关能力统一使用@apollo/client提供的API:npm uninstall apollo-boost - 第二步:修正客户端初始化代码
修改App.js的导入和客户端初始化逻辑,删除从apollo-boost的导入,统一从@apollo/client引入依赖:// 修正导入,ApolloClient也从@apollo/client导入 import { ApolloProvider, InMemoryCache, ApolloClient } from "@apollo/client"; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Homepage from "./pages/Homepage"; import LoginPage from "./pages/LandingPage"; import Auth from "./utils/auth"; import Verify from "./pages/VerifyUserPage"; const client = new ApolloClient({ uri:"http://localhost:3001/graphql", cache:new InMemoryCache(), // 跨域场景下如果需要携带cookie,可打开下面配置 // credentials: 'include' }) - 第三步:优化服务端启动时序(可选,避免后续偶发问题)
你当前服务端的异步启动逻辑没有等待Apollo中间件挂载完成就启动端口监听,极端场景下会出现请求时序问题,同时你已经全局配置了CORS,不需要在applyMiddleware中重复配置CORS避免头冲突,调整server.js启动逻辑:async function startServer() { apolloServer = new ApolloServer({ typeDefs, resolvers, csrfPrevention:true, cache:'bounded' }); await apolloServer.start(); // 全局已配置cors,这里设为false避免重复配置冲突 apolloServer.applyMiddleware({ app, cors: false }); console.log(`🚀 Server ready at http://localhost:${PORT}${apolloServer.graphqlPath}`); // 等Apollo中间件挂载完成后再监听端口 db.once("open", () => { app.listen(PORT, () => { print(`Now listening on localhost:${PORT}`, new Error(), {isClient: false, }); }); }); } startServer(); // 删除文件中原来db.once包裹的app.listen逻辑,避免重复启动
内容的提问来源于stack exchange,提问作者Alec
相关产品推荐
相关产品推荐

