gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.27k stars 10.31k forks source link

"The result of this StaticQuery could not be fetched" when calling useStaticQuery within a custom hook and declaring the query in the usage of the custom hook #13764

Closed MeLlamoPablo closed 5 years ago

MeLlamoPablo commented 5 years ago

Description

Executing gatsby build throws the following error:

The result of this StaticQuery could not be fetched.

This is likely a bug in Gatsby and if refreshing the page does not fix it, please open an issue in https://github.com/gatsbyjs/gatsby/issues

when using a custom hook that uses useStaticQuery, and passes the query parameter as a variable, as opposed to the example in the docs, which inlines the query in the useStaticQuery call.

An example of a custom hook which causes this behavior is:

export const useHelloWorld = query => useStaticQuery(query)
    .allFile
    .nodes[0]
    .childYaml
    .hello

Steps to reproduce

I have set up a demo repo to demonstrate the issue. In order to reproduce it:

$ git clone git@github.com:MeLlamoPablo/gatsby-static-query-bug-demo.git
$ cd gatsby-static-query-bug-demo
$ yarn
$ git checkout 546024b
$ yarn build # This should work
$ git checkout -
$ rm -rf .cache && yarn build # This should error

The code that causes the bug is the following:

diff --git a/src/components/header.js b/src/components/header.js
index 920b133..22ec421 100644
--- a/src/components/header.js
+++ b/src/components/header.js
@@ -1,9 +1,10 @@
-import { graphql, Link, useStaticQuery } from "gatsby"
+import { graphql, Link } from "gatsby"
 import PropTypes from "prop-types"
 import React from "react"
+import { useHelloWorld } from "../hooks/useHelloWorld"

 const Header = ({ siteTitle }) => {
-  const data = useStaticQuery(graphql`
+  const hello = useHelloWorld(graphql`
     {
       allFile(filter: {relativePath: {regex: "/Header\\/.+\\\\.yml/"}}) {
         nodes {
@@ -15,8 +16,6 @@ const Header = ({ siteTitle }) => {
     }
   `)

-  const hello = data.allFile.nodes[0].childYaml.hello
-
   return (
     <header
       style={{
diff --git a/src/hooks/useHelloWorld.js b/src/hooks/useHelloWorld.js
new file mode 100644
index 0000000..9d9f358
--- /dev/null
+++ b/src/hooks/useHelloWorld.js
@@ -0,0 +1,7 @@
+import { useStaticQuery } from "gatsby"
+
+export const useHelloWorld = query => useStaticQuery(query)
+  .allFile
+  .nodes[0]
+  .childYaml
+  .hello

Expected result

The yarn build command should work successfully.

Actual result

The yarn build command fails with the error mentioned above.

Environment

  System:
    OS: Linux 4.15 Ubuntu 18.04.2 LTS (Bionic Beaver)
    CPU: (8) x64 Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
    Shell: 5.4.2 - /usr/bin/zsh
  Binaries:
    Node: 8.12.0 - /tmp/yarn--1556700432647-0.45796071280625616/node
    Yarn: 1.15.2 - /tmp/yarn--1556700432647-0.45796071280625616/yarn
    npm: 6.4.1 - ~/.nvm/versions/node/v8.12.0/bin/npm
  Languages:
    Python: 2.7.15 - /usr/bin/python
  Browsers:
    Chrome: 74.0.3729.108
    Firefox: 66.0.3
  npmPackages:
    gatsby: ^2.3.34 => 2.3.34 
    gatsby-image: ^2.0.41 => 2.0.41 
    gatsby-plugin-manifest: ^2.0.29 => 2.0.29 
    gatsby-plugin-offline: ^2.0.25 => 2.0.25 
    gatsby-plugin-react-helmet: ^3.0.12 => 3.0.12 
    gatsby-plugin-sharp: ^2.0.35 => 2.0.35 
    gatsby-source-filesystem: ^2.0.33 => 2.0.33 
    gatsby-transformer-sharp: ^2.1.18 => 2.1.18 
    gatsby-transformer-yaml: ^2.1.12 => 2.1.12 

Thanks for your help!

jonniebigodes commented 5 years ago

@MeLlamoPablo i've picked up on your issue and i have a answer for your:

From my undestanding of Gatsby, this is technically not a bug, it's reported as such but it's not. What you're doing from Gatsby's point of view is using a variable with a StaticQuery, that's not possible, more on that here. There's some work being done in that department but as it's alot of moving parts involved some more time will be necessary to make it work seamlessly.

To make this work you would have to transform your hook code from:

import { useStaticQuery } from "gatsby"

export const useHelloWorld = query => useStaticQuery(query)
  .allFile
  .nodes[0]
  .childYaml
  .hello
export default useHelloWorld

To:

const useHelloWorld = () => {
  const { allFile } = useStaticQuery(
    graphql`
      {
        allFile(filter: {relativePath: {regex: "/Header\\/.+\\\\.yml/"}}) {
          nodes {
            childYaml {
              hello
            }
          }
        }
      }
    `
  )
  return allFile
}

In your /src/components/header.js you would have to make some adjustments to make it show anything without any kind of errors transforming your component into:

import React from "react"
import { Link } from "gatsby"
import PropTypes from "prop-types"
import useHelloWorld from "../hooks/useHelloWorld"

const Header = () => {
  const { nodes } = useHelloWorld()

  return (
    <header
      style={{
        background: `rebeccapurple`,
        marginBottom: `1.45rem`,
      }}
    >
      <div
        style={{
          margin: `0 auto`,
          maxWidth: 960,
          padding: `1.45rem 1.0875rem`,
        }}
      >
        <h1 style={{ margin: 0 }}>
          <Link
            to="/"
            style={{
              color: `white`,
              textDecoration: `none`,
            }}
          >
            {
              nodes[0].childYaml.hello!==undefined?nodes[0].childYaml.hello:<div><h1>nothing was returned</h1></div>
            }
          </Link>
        </h1>
      </div>
    </header>
  )
}

Header.propTypes = {
  siteTitle: PropTypes.string,
}

Header.defaultProps = {
  siteTitle: ``,
}

export default Header

With my proposed changes, issuing gatsby develop and opening up http://localhost:8000 i'm presented with: pablo_build

MeLlamoPablo commented 5 years ago

However, this does work:

diff --git a/src/components/header.js b/src/components/header.js
index 920b133..2ddcd08 100644
--- a/src/components/header.js
+++ b/src/components/header.js
@@ -3,7 +3,7 @@ import PropTypes from "prop-types"
 import React from "react"

 const Header = ({ siteTitle }) => {
-  const data = useStaticQuery(graphql`
+  const query = graphql`
     {
       allFile(filter: {relativePath: {regex: "/Header\\/.+\\\\.yml/"}}) {
         nodes {
@@ -13,7 +13,9 @@ const Header = ({ siteTitle }) => {
         }
       }
     }
-  `)
+  `
+
+  const data = useStaticQuery(query)

   const hello = data.allFile.nodes[0].childYaml.hello

(This diff can be applied to https://github.com/MeLlamoPablo/gatsby-static-query-bug-demo/commit/74002adb0d54261ef3214fac6ecfe2b8e87fb18c)

So the problem doesn't come from storing the query in a variable, it actually comes from passing the query to a hook other than useStaticQuery. This will error:

diff --git a/src/components/header.js b/src/components/header.js
index 2ddcd08..aec6c2b 100644
--- a/src/components/header.js
+++ b/src/components/header.js
@@ -2,8 +2,10 @@ import { graphql, Link, useStaticQuery } from "gatsby"
 import PropTypes from "prop-types"
 import React from "react"

+const useQuery = query => useStaticQuery(query)
+
 const Header = ({ siteTitle }) => {
-  const query = graphql`
+  const data = useQuery(graphql`
     {
       allFile(filter: {relativePath: {regex: "/Header\\/.+\\\\.yml/"}}) {
         nodes {
@@ -13,9 +15,7 @@ const Header = ({ siteTitle }) => {
         }
       }
     }
-  `
-
-  const data = useStaticQuery(query)
+  `)

   const hello = data.allFile.nodes[0].childYaml.hello

(This diff can be applied to the result of applying the previous diff.)

So I'd argue that either this is a bug, or this behavior must be documented properly, as it doesn't seem intuitive to me. And I suggest that the error message is changed too because it does make it seem like it is a bug.

jonniebigodes commented 5 years ago

@MeLlamoPablo first of all, could you please correct your code, linting and otherwise, just don't post the code straight from a diff. It's a bit hard to read and understand, if anyone should pickup on the issue at least he/she could read it and understand the code block. From what i 've read your first block of code is a basic implementation of graphql, and it's fine, the query string itself is static, not mutated.

When you use this type of approach: Header.js

import { graphql, Link } from "gatsby"
import PropTypes from "prop-types"
import React from "react"
import { useHelloWorld } from "../hooks/useHelloWorld"

const Header = ({ siteTitle }) => {
  const hello = useHelloWorld(graphql`
    {
      allFile(filter: {relativePath: {regex: "/Header\\/.+\\\\.yml/"}}) {
        nodes {
          childYaml {
            hello
          }
        }
      }
    }
  `)

  return (
    <header
      style={{
        background: `rebeccapurple`,
        marginBottom: `1.45rem`,
      }}
    >
      <div
        style={{
          margin: `0 auto`,
          maxWidth: 960,
          padding: `1.45rem 1.0875rem`,
        }}
      >
        <h1 style={{ margin: 0 }}>
          <Link
            to="/"
            style={{
              color: `white`,
              textDecoration: `none`,
            }}
          >
            {hello}
          </Link>
        </h1>
      </div>
    </header>
  )
}

Header.propTypes = {
  siteTitle: PropTypes.string,
}

Header.defaultProps = {
  siteTitle: ``,
}

export default Header

Your custom hook, useHelloWorld.js

/**
 * 
 * @param {*} value  will contain the graphql query
 * @returns {Array} witht he result of the query
 */
const useHelloWorld = value => {

  const { allFile } = useStaticQuery(
    value

  )
  return allFile
}

Technically you're using something that is variable to contain the query, that is passed down as a argument to your custom hook. Even if you hard coded it like it's above, it's still technically a variable. And useStaticQuery hook don't like that, the query itself has to be declared inside, so that when it's evaluated, parsed and built during the build process and then return the appropriate data. A bug? I don't see it that way, according to your code and the documentation it's working as it should. Better documented? Probably, has it might be a bit misleading and could originate issues like this one.

mcclaskiem commented 5 years ago

I am getting this error based on where I import the component that uses it.

I have tried it inside of my layouts file as well as inside of the header that sits inside of that.

After moving it into pages/index.js it works as expected.

In my case, I want to be able to use this staticQuery at a global level since it is for a navigation component that is accessible from every page.

Any suggestions?

gatsbot[bot] commented 5 years ago

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contributefor more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 💪💜

gatsbot[bot] commented 5 years ago

Hey again!

It’s been 30 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it.

Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks again for being part of the Gatsby community!

heytulsiprasad commented 4 years ago

Is there anyone who faced this issue randomly out of nowhere? I don't know why but my site is working fine locally everytime I run gatsby develop but when pushing to Vercel (I am using vercel for deployments) I am getting this exact issue but only sometimes and randomly. Its like 9/10 times, and I get this done by doing another deployment and voila it works!

It's not like I'm stuck or something, but I feel like I should know why this happens and if there's any real issue or bug why doesn't it show up while running locally?

alexnault commented 4 years ago

@heytulsiprasad I have the exact same situation. develop is fine, but I get this issue on prod with Vercel on random deployments.

heytulsiprasad commented 4 years ago

Do you think it's a platform specific issue? Like on Vercel itself? @alexnault

I think it has to do it Gatsby as the error itself says it, but as folks from Gatsby have faced and closed this issue a year ago, so maybe it hasn't been really an issue for them. 🤔

alexnault commented 4 years ago

@heytulsiprasad It could be related to Vercel, but I doubt it. People seem to have had this issue not long ago on Heroku. https://github.com/gatsbyjs/gatsby/issues/21392

To me, it sounds related to gatsby build in general.

daydream05 commented 4 years ago

I get this issue as well using Docker

fono97 commented 4 years ago

I got the same issue on netlify and namecheap. gatsby develop is ok. however, when I built thing for deployment, things doesn't work as expected. this is the fonoandy.com

alexnault commented 4 years ago

I was using a Gatsby starter with outdated dependencies. So I've upgraded every Gatsby-related packages to latest versions and it fixed the issue for me: https://github.com/alexnault/alexnault.dev/commit/4cfd976bab722c5e3757e31e6d9f815cf212c0e1#diff-b9cfc7f2cdf78a7f4b91a753d10865a2

perliedman commented 4 years ago

I still have the same problem as described by @alexnault, but unfortunately upgrading gatsby and related deps did not help...

Here are the only gatsby-related deps I have in package.json:

    "gatsby": "^2.24.80",
    "gatsby-plugin-postcss": "^2.3.12",

It seems to be 50/50 if the build produces a valid bundle or not, so I routinely make a second dummy deploy to Vercel to get rid of The result of this StaticQuery could not be fetched.

The query error appears in my Seo component, which is a straight up copy of the code here: https://www.gatsbyjs.com/docs/add-seo-component/

My site is pretty trivial since I'm a Gatsby beginner.

alacret commented 3 years ago

Experiencing the same problem here, on a ubuntu VPS with nginx