为啥我在函数内部调用时会收到“错误:无效的挂钩调用”?

Posted

技术标签:

【中文标题】为啥我在函数内部调用时会收到“错误:无效的挂钩调用”?【英文标题】:Why do I get 'Error: Invalid hook call' when I am calling inside a function?为什么我在函数内部调用时会收到“错误:无效的挂钩调用”? 【发布时间】:2021-04-22 04:00:51 【问题描述】:

当我在 Next.js 应用程序上使用挂钩时,我收到 'Error: Invalid hook call'。我不知道为什么我会收到这个错误,因为我认为它是在函数组件中调用的?

Server Error
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
This error happened while generating the page. Any console logs will be displayed in the terminal window.
Source
pages/index.js (16:44) @ getStaticProps
  14 | 
  15 | export const getStaticProps = async () => 
> 16 |   const  data, loading, error  = useQuery(LINGO_QUERY);
     |                                            ^
  17 | 
  18 |   return 
  19 |     props: 

在此处查看我的代码框:https://codesandbox.io/s/empty-sea-hjunv

【问题讨论】:

它不是一个函数组件,你不能在那里使用钩子,我想你应该调用 fetch。 我正在使用 Apollo,所以我不需要使用 fetch? 你使用了 apollo hooks,所以你只能在函数组件中使用它们。 【参考方案1】:

你不能在 react 组件之外使用钩子。

那么,在 nextjs 中,getStaticProps 是在服务器端上下文中使用的函数,并且在构建时预渲染。

https://nextjs.org/docs/basic-features/data-fetching

【讨论】:

谢谢,我已经更新了我的沙盒。我现在收到了TypeError: Cannot read property 'map' of undefined,但我以为我已经在挂钩中定义了它? 您定义了它,但我认为他的值为 null 或未定义(因为 .map 仅可用于数组)。也许您的查询效果不佳,或者您没有任何数据可以在 graphql 中获取 我查看了 GraphQL 操场并返回了我预期的结果。目前数据库中只有一个词: "data": "allTerms": [ "id": "600456129d8f3455d5631403", "term": "accelerator", "slug": "accelerator" ] 好的,但您尝试使用 .map 遍历 data,但它不是数组。查看您的 GraphQL 响应。我认为您需要将 .map 与 allTerms 数组一起使用。 data.allTerms.map((...) => ... ) 谢谢。那会起作用,但我认为它不会填充页面,因为它需要等待数据并因此返回未定义。这应该用 await 完成吗?【参考方案2】:

你不能在组件外使用钩子。你的getStaticProps 不是一个组件,它是一个你用来返回道具的函数。

您可以在此处阅读更多信息:https://reactjs.org/warnings/invalid-hook-call-warning.html#breaking-the-rules-of-hooks

只需在组件中使用 useQuery 钩子并使用它来获取一些数据并定期呈现。

您可能正在某处作为常规函数执行该函数。

要使用钩子,你需要在组件中调用它,这是一个规则,因为钩子可能会返回一些 jsx,而 React 将其作为强制性的。

【讨论】:

谢谢。我已经更新了我的代码框,因为现在我得到了TypeError: Cannot read property 'map' of undefined。但是data是在钩子里定义的,不是吗? @Anthony 您需要更新您的代码框,它无法正常工作。显示内部服务器错误。您需要添加所有依赖项 我认为这是由于我的 API 在 localhost 上运行,我不确定如何让它在沙箱上运行。该查询位于沙盒的 api 目录中,我已经在 GraphQL 操场上进行了本地测试,它返回了预期的结果。 "data": "allTerms": [ "id": "600456129d8f3455d5631403", "term": "accelerator", "slug": "accelerator" ] 那么你需要首先检查它是否未定义。不能当场使用.map。添加三元data ? data.map... : null

以上是关于为啥我在函数内部调用时会收到“错误:无效的挂钩调用”?的主要内容,如果未能解决你的问题,请参考以下文章

× 错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用。[ReactJS]

React Hooks:在验证时实例化状态挂钩错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用

无效的挂钩调用。钩子只能在使用 react-apollo 的函数组件内部调用

错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。 【我还在用函数组件】

React 17 - 添加 Evergreen UI 窗格会导致错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用

在Stripe + React中发生无效的挂钩调用错误