Using the useStaticQuery hook outside of a function component is not allowed and will result in an invalid hook call error. Remember to only call

I am currently facing an issue while trying to retrieve values using useStaticQuery from my gatsby-config.js file. Below are snippets of my code.

Does anyone have any suggestions on how to resolve this problem?

Thank you in advance.

Repository:
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"
  }
}

Answer №1

The issue lies in the first letter of the component's name not being capitalized;

Moreover, useStaticQuery should be used to render the component's children that rely on this query within the component itself;

The modified version of the UseSiteMetadata component would be:

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>
  );

As for the revised Header component:

import * as React from "react";
import { UseSiteMetadata } from 'siteMetadata'


export default class Header extends React.Component {
  render() {
    return (<UseSiteMetadata /> )
  }
}

Answer №2

This question may be dated, but it's possible that others will come across the same issue.

The issue lies in returning a string from the title found in the useSiteMetadata hook, only to destructure it in the Header component.

It seems like you intended to return an object from the hook:

return {title: site.siteMetadata.title};

Alternatively, for consistency with the hook name:

return site.siteMetadata;

Remember not to capitalize hooks or treat them as components as mentioned in other responses. Refer to the React documentation for more information on this.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What methods can I use to integrate a Google HeatMap into the GoogleMap object in the Angular AGM library?

I am trying to fetch the googleMap object in agm and utilize it to create a HeatMapLayer in my project. However, the following code is not functioning as expected: declare var google: any; @Directive({ selector: 'my-comp', }) export class MyC ...

Difficulty establishing a connection between Typescript and Postgres results in a prolonged

I am attempting to establish a connection to a Postgres database using typescript. For the ORM, I have opted for sequelize-typescript. The issue lies in the fact that the script seems to hang at await sequelize.sync();. Below is the content of the sequeliz ...

Facing an issue with grafbase | graphql query - runs smoothly in development environment but encountering errors in production

In my attempt to create a dribble clone, I encountered an issue while using grafbase for data querying. The problem arises in the production environment with an error stating that the "category" field has an invalid type of "null" when it is expected to be ...

Unable to transfer props object to React component using TypeScript

Apologies if this seems like a basic issue, but I've been struggling with it for the past two days. I'm currently working on writing a simple unit test in Vitest that involves rendering a component to the screen and then using screen.debug(). The ...

``Why Ionic 3 Popover Sizes Should Adapt to Different Screen

Currently in my Ionic 3 project, I am utilizing a popover with a set height using the following code snippet: editOpty(rw){ let popover = this.editOptyPopup.create(EditOptyPopoverComponent, rw, { cssClass: 'edit-opty-popover'}); popover ...

Evaluating Angular/Typescript and its capabilities

I seem to be struggling with the concept of how eval functions in TypeScript/Angular. Can someone provide some guidance on how to make eval work in this scenario? Although the logic may not be perfect in this demo program, I just need help figuring out how ...

Converting JSON into an interface in TypeScript and verifying its validity

How can I convert a JSON string to a nested interface type and validate it? Although my model is more complex, here is an example: export interface User = { name: Field; surname: Field; }; export interface Field = { icon: string; text: string; vis ...

How can we use tsyringe (a dependency injection library) to resolve classes with dependencies?

I seem to be struggling with understanding how TSyringe handles classes with dependencies. To illustrate my issue, I have created a simple example. In my index.tsx file, following the documentation, I import reflect-metadata. When injecting a singleton cl ...

Using Angular 5 to access a variable within a component while iterating through a loop

I am currently in the process of transferring code from an AngularJS component to an Angular 5 component. Within my code, I have stored an array of objects in a variable called productlist. In my previous controller, I initialized another empty array nam ...

Automatically arrange TypeScript import statements in alphabetical order in WebStorm / PhpStorm

I am using tslint with the default config tslint:recommended and I am looking to minimize the number of rules I need to customize. Some rules require that imports be alphabetized: src/core/task/TaskMockDecorator.ts[2, 1]: Imports within a group must be a ...

Issue with ngx-extended-pdf-viewer when using URL

I'm struggling to display my PDF file on a viewer using a URL in TypeScript. I am utilizing ngx-extended-pdf-viewer. Below is a snippet of my code with the URL replaced: <ngx-extended-pdf-viewer *ngIf="!isFirefox" [src]="'http://www.chi ...

Using TypeScript to work with asynchronous child_process.exec operations

Having trouble implementing a child_process.exec call with TypeScript and finding error handling to be quite challenging. Here's the basic idea of what I'm attempting: import { promisify } from "util"; import { exec, ExecException } fr ...

Tips for utilizing the "??=" syntax in Typescript

let x; x ??= 'abc' console.log(x); // abc Running the code above in the browser console does not cause any issues. However, when attempting to run it in TypeScript, an error is thrown. SyntaxError: Unexpected token '??=' Here is my c ...

Using styled-components and typescript to override props

Currently, I am faced with the challenge of using a component that necessitates a specific property to be set. My goal is to style this component with the required property already defined, without having to manually specify it again during rendering. Howe ...

Unexpected Union Type Return from Apollo Server

When I call my resolver to return a union type (either a User or an object with a message key and value of type String, such as my UserNotFoundError type), it always comes back with "__typename": "User". Why is this happening and how ca ...

Does Angular 8 development mode implement tree-shaking?

I am curious to know if tree-shaking occurs during Angular 8 development mode. When running the following command: ng build I understand that tree-shaking happens when I use the command below: ng build --optimization=true|false ...

Tips for invoking TypeScript code from Rust WebAssembly

Currently, I am considering transitioning a slow TypeScript library (jackson-js) to WASM using rust. This particular library has various dependencies, like reflect-metadata for example. These dependencies are already created and accessible on npmjs. The ...

Connect a datetime-local typed input to a Date attribute in Angular 2

Can a property of type Date in a component be bound to an HTML5 input with the type attribute set as datetime-local? For example, I have a component with the following property: public filterDateFrom: Date; And in my template, I am trying to bind this p ...

Guide to highlighting manually selected months in the monthpicker by utilizing the DoCheck function in Angular

I'm facing an issue and I could really use some assistance. The problem seems quite straightforward, but I've hit a roadblock. I have even created a stackblitz to showcase the problem, but let me explain it first. So, I've developed my own t ...

Typescript's Confusion with Array Types: Understanding Conditional Types

Here is the setup I have. The concept is to receive a generic and options shape, deduce the necessary options based on the generic and the type key of the options shape, and appropriately restrict the options. type OptionProp<T extends string | boolean& ...