【问题标题】:useStaticQuery: Invalid hook call. Hooks can only be called inside of the body of a function componentuseStaticQuery:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用
【发布时间】: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 = () =&gt; (&lt;h1&gt;... &lt;/h1&gt;); export default Header;
  • @artem 非常感谢您的帮助。你让我今天一整天都感觉很好。终于成功了

标签: typescript graphql gatsby


【解决方案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 /> )
      }
    }
    
    

    【讨论】:

    • 你在这里添加了一个组件而不是一个钩子。请不要使用像组件这样的钩子。请参阅反应文档以获取更多信息。
    猜你喜欢
    • 2019-11-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 2021-12-18
    • 2020-07-22
    • 2020-02-24
    • 1970-01-01
    相关资源
    最近更新 更多