useStaticQuery:无效的挂钩调用。挂钩只能在功能组件的主体内部调用

时间:2019-08-04 03:41:53

标签: typescript graphql gatsby

我正在尝试通过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"
  }
}

2 个答案:

答案 0 :(得分:3)

组件名称中的第一个字母未大写,从而导致此问题;

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 /> )
  }
}

答案 1 :(得分:0)

这个问题很老了,但其他人也可能会遇到。

问题是您返回在 useSiteMetadata 挂钩中的 title 中找到的字符串,然后在 Header 组件中破坏它。

我认为您打算从钩子中返回一个对象:

return {title: site.siteMetadata.title};

或者更符合钩子名称:

return site.siteMetadata;

请不要将钩子大写,也不要像其他答案中建议的那样使用它们。请参阅 react 文档以了解原因。