useStaticQuery:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用
Posted
技术标签:
【中文标题】useStaticQuery:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用【英文标题】:useStaticQuery: Invalid hook call. Hooks can only be called inside of the body of a function component 【发布时间】:2019-12-12 02:14:25 【问题描述】:我正在尝试通过 useStaticQuery
从 gatsby-config.js 获取值。
我的代码如下。
有人有解决这个问题的想法吗?
提前谢谢你
回购https://github.com/koji/portfolio
package.json
"dependencies":
"@babel/core": "^7.5.5",
"gatsby": "^2.13.28",
"gatsby-link": "^2.2.2",
"gatsby-plugin-react-helmet": "^3.1.2",
"gatsby-plugin-sass": "^2.1.3",
"gatsby-plugin-typescript": "^2.1.2",
"gatsby-source-filesystem": "^2.1.8",
"gatsby-source-instagram-all": "^2.0.5",
"gatsby-transformer-remark": "^2.6.10",
"node-sass": "^4.12.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"webpack": "^4.36.1"
,
"devDependencies":
"@types/react": "^16.8.24",
"@types/react-dom": "^16.8.5",
"@types/react-helmet-async": "^1.0.0",
"env-cmd": "^9.0.3",
"eslint-plugin-react-hooks": "^1.6.1",
"gatsby-plugin-tslint": "^0.0.2",
"tslint": "^5.18.0",
"tslint-loader": "^3.5.4",
"tslint-react": "^4.0.0",
"typescript": "^3.5.3"
siteMetadata.ts
import useStaticQuery, graphql from "gatsby";
export const useSiteMetadata = () =>
const site = useStaticQuery(
graphql`
query
site
siteMetadata
title
author
`);
return site.siteMetadata.title;
;
import * as React from "react";
import useSiteMetadata from 'siteMetadata'
export default class Header extends React.Component
render()
const title = useSiteMetadata();
return (
<h1>
<Link className=headerStyles.title to="/">
title
</Link>
</h1>
)
gatsby-config.js
module.exports =
siteMetadata:
title: "page title",
author: "me"
【问题讨论】:
useSiteMetadata
是一个函数,你必须调用它才能得到它返回的值(也就是写useSiteMetadata()
。还有,它不是一个普通的函数,它是一个 React 钩子,这意味着您只能在渲染期间从功能性反应组件内部调用它。调用它来初始化模块范围内的某些变量是行不通的。
现在错误是因为钩子不能在类组件中使用。它仅适用于功能组件,您需要 rewrite your component 类似于 const Header: React.FC = () => (<h1>... </h1>); export default Header;
@artem 非常感谢您的帮助。你让我今天一整天都感觉很好。终于成功了
【参考方案1】:
这个问题很老,但其他人也可能会遇到。
问题是您在 useSiteMetadata 钩子中返回在 title 中找到的字符串,然后在 Header 组件中将其销毁。
我认为你的意思是从钩子中返回一个对象:
return title: site.siteMetadata.title;
或者更符合钩子名称:
return site.siteMetadata;
请不要大写钩子,也不要像其他答案中建议的那样使用它们。查看 react 文档以了解原因。
【讨论】:
【参考方案2】:组件名称中的第一个字母未大写,导致此问题;
而useStaticQuery
不是这样工作的,您需要在您使用它的组件内呈现依赖于此查询的组件的子组件;
组件 UseSiteMetadata 将是:
import useStaticQuery, graphql from "gatsby";
export const useSiteMetadata = () =>
const site = useStaticQuery(
graphql`
query
site
siteMetadata
title
author
`);
return (
<h1>
<Link className=headerStyles.title to="/">
site.siteMetadata.title
</Link>
</h1>
);
Header
将是:
import * as React from "react";
import UseSiteMetadata from 'siteMetadata'
export default class Header extends React.Component
render()
return (<UseSiteMetadata /> )
【讨论】:
你在这里添加了一个组件而不是一个钩子。请不要使用像组件这样的钩子。请参阅反应文档以获取更多信息。以上是关于useStaticQuery:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用的主要内容,如果未能解决你的问题,请参考以下文章
使用 useHistory、useLocation 挂钩的挂钩调用无效
错误 无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用