React中使用useQuery触发Invalid Hook等错误求助
问题根源与解决方案
核心错误原因
你在普通函数getDocumentProps中调用了React Hook(useQuery),违反了React Hook的核心规则:Hook只能在React函数组件的顶层,或者自定义Hook的顶层调用。这直接导致了所有三个错误:
- 第一个警告是React直接提示你违反Hook规则;
- 第二个
Cannot read property 'useContext' of null是因为useQuery内部依赖React Context传递Apollo客户端实例,在非组件/非Hook环境下调用时,Context无法被正确获取,最终返回null; - 第三个
getDocumentProps is not a function大概率是你调用该函数的方式有误(比如误将其当作React组件渲染),但根源还是前面的Hook使用错误。
解决方案分两种场景处理
场景1:在服务端/静态生成函数中使用(比如Next.js的getStaticProps/getServerSideProps)
这类函数属于普通异步函数,不能使用Hook,需要手动初始化Apollo客户端并调用client.query()方法:
import { ApolloClient, InMemoryCache } from '@apollo/client'; // 假设你的GraphQL查询定义在这里 import { getMetaData } from './your-queries'; // 初始化Apollo客户端实例 const client = new ApolloClient({ uri: '你的GraphQL服务端点地址', cache: new InMemoryCache(), }); export async function getDocumentProps(pageProps) { try { const { data } = await client.query({ query: getMetaData, variables: { blockname: "MetaData" }, }); return { props: { title: data.title, description: data.description, author: data.author, type: data.type, image: data.image, }, }; } catch (error) { console.error('数据获取失败:', error); return { props: { error: `Oops there has been an error: ${error.message}`, }, }; } }
场景2:在React组件中使用
将getDocumentProps改造成自定义Hook,这样就能合法使用useQuery:
import { useQuery } from '@apollo/client'; import { getMetaData } from './your-queries'; // 自定义Hook,命名以use开头(Hook规范要求) export function useDocumentProps() { const { data, error, loading } = useQuery(getMetaData, { variables: { blockname: "MetaData" }, }); if (loading) return { loading: true }; if (error) return { error: `Oops there has been an error: ${error.message}` }; return { loading: false, documentData: { title: data.title, description: data.description, author: data.author, type: data.type, image: data.image, }, }; } // 在React组件中调用自定义Hook function YourComponent() { const { loading, error, documentData } = useDocumentProps(); if (loading) return <div>加载中...</div>; if (error) return <div>{error}</div>; return ( <div> <h1>{documentData.title}</h1> <p>{documentData.description}</p> </div> ); }
额外检查项
针对getDocumentProps is not a function错误:
- 确认函数的导出方式(命名导出/默认导出)和导入方式一致;
- 检查调用该函数时是否误将其当作React组件(比如用
<getDocumentProps />的方式渲染)。
内容的提问来源于stack exchange,提问作者sokratesli
相关产品推荐
相关产品推荐

