Search code examples
reactjscomponentsgatsby

Using a static query in a React class component


I trying to use a static query in a react class component in Gatsby.

import * as React from "react"
    import '../styles/layout.scss'
    import Layout from '../components/layout'
    import { useStaticQuery, graphql } from 'gatsby'
    import { container } from '../styles/mystyles.module.scss'
    class IndexPage extends React.Component {
        constructor(props) {
            super(props);
        }
        render() {
           return  <Layout>
                <div>
                    <h1 className={container}>hello </h1>
                    <div>This is my container</div>
                </div>
            </Layout>
        }
    }
    const data = useStaticQuery(graphql`
        query HeaderQuery {
          site {
            siteMetadata {
              title
            }
          }
        }
      `)
    
    export default IndexPage

I get the error

19:14 error React Hook "useStaticQuery" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks

Does this mean it is not possible and it has to be a function component?


Solution

  • The issue is that you're trying to call a function at the “top level” (out of a function), and hooks only work when they are called from inside a function component. E.g.:

    const YourComponent = () => {
      const data = useStaticQuery(yourQuery)
    }
    

    If you don’t want to use a function component, you can still use the StaticQuery higher-order component instead:

    export default (props) => 
      <StaticQuery query={yourQuery}>
        {({ data }) => <SomeComponent {...data} {...props} />}
      </StaticQuery>
    

    …or like this…

    class SomeComponent extends React.Component {
      render() {
        return (
          <StaticQuery query={yourQuery}>
            {({ data }) => <div>{data.site.title}</div>}
          </StaticQuery>
        )
      }
    }