Gatsby: [v2] Sometimes, a StaticQuery keeps loading forever

Created on 18 May 2018  ·  32Comments  ·  Source: gatsbyjs/gatsby

Description

As stated in the title, some of my GraphQL queries enclosed in a StaticQuery component refuse to run in development mode until I change the content of its container page and save it.

Steps to reproduce

  1. Clone simonyiszk/mvk-web@5d80daac7f951904746aede0ee88f9dc2e9dc59e
  2. Install dependencies using yarn
  3. Run yarn develop and see the news section of the home page:
    image

The issue can be fixed by changing the content of src/pages/index.jsx.

Expected result

News items should be displayed:
image

Actual result

News items don't get displayed (as shown above).

Environment

  • Gatsby version (npm list gatsby): 2.0.0-alpha.39
  • gatsby-cli version (gatsby --version): 2.0.0-alpha.39
  • Node.js version: 8.11.2
  • Operating System: Windows 10 x64

File contents (if changed)

Please see the related git repository.

bug

Most helpful comment

maybe just go StaticQuery all the way? Is there an advantage for the page query format? I guess it gets a bit messy if you need query results in the top level component lifecycles? could provide like a HOC thing tho for that :P

I'd agree it seems a bit surprising that StaticQuery doesn't work in some places. I'm also pretty sure the Relay compiler can coalesce root queries into a single query, perhaps we could leaverage that?

All 32 comments

It turns out that StaticQuery components on pages _(not regular components)_ aren't even run by gatsby/dist/internal-plugins/query-runner/query-runner.js.

I came to this conclusion by putting console.log(props.query, staticQueryData[props.query]) inside StaticQueryContext.Consumer, straight after https://github.com/gatsbyjs/gatsby/blob/f001bb90d72ea2cadd42ef83c4bbdae64d7535f3/packages/gatsby/cache-dir/gatsby-browser-entry.js#L19-L21

Matching the resulting IDs with the ones appearing in query-runner.js led me to believe that if a StaticQuery is part of a page, it will not be executed until the page's corresponding file is modified and saved during development.

Also, queries through StaticQuery components on pages don't get passed to page-query-runner.js through runQueriesForPathnames:

https://github.com/gatsbyjs/gatsby/blob/f001bb90d72ea2cadd42ef83c4bbdae64d7535f3/packages/gatsby/src/internal-plugins/query-runner/page-query-runner.js#L100-L116

_(I've console.logged every queryJob but could only find StaticQuery queries made through regular, non-page components.)_

Yeah, each page or component can only have one query. Pages with the same page queries from v1 and regular components with StaticQuery. This was surprising I guess? We could add support I suppose for StaticQuery in pages but I worry this could cause confusion as people might expect to be able to pass page variables into StaticQuery queries.

maybe just go StaticQuery all the way? Is there an advantage for the page query format? I guess it gets a bit messy if you need query results in the top level component lifecycles? could provide like a HOC thing tho for that :P

I'd agree it seems a bit surprising that StaticQuery doesn't work in some places. I'm also pretty sure the Relay compiler can coalesce root queries into a single query, perhaps we could leaverage that?

maybe a HOC is better generally even, so folks aren't tempted to think they can use props on the static query?

gatsby.withQuery(Component, graphql`

`)

I'm not opposed to the hoc idea. Even like it. Just not sure how to make it clear which queries take variables and which don't.

could theoretically have compile time error on that...i will generally there was a better way of signalling that variable values are provided by the gatsby API, i am sort of out of ideas on that tho :/

this is good example of where the relay style first-class colocation and top level limited queries has an advantage over the apollo style query-all-the-things approach (to me anyway). If you just use fragments and limite queries to route roots (pages) you get the variable values from the page automatically and can even reference them in fragments via the @arguments() directive, since it's all gathered into a single query.

Though tbf, it's already a potent source of confusion to people trying to understand how and where variables get into page queries :-P

I'm mildly hopeful that the name _Static_Query will help with that but...

can even reference them in fragments via the @arguments() directive

oooo we should add support for that.

How does Relay do standalone queries?

How does Relay do standalone queries?

Similar to apollo, you can add a Query like component where-ever and pass in variables, i guess the odd bit with Gatsby is that the query is actually _run_ ahead of time, not just extracted

oooo we should add support for that.

We probably already have support for it, i think it's just a compiler feature. may be we need a more definitive guide to using graphql throughout an app.

Similar to apollo, you can add a Query like component where-ever and pass in variables, i guess the odd bit with Gatsby is that the query is actually run ahead of time, not just extracted

Yeah, ok <StaticQuery> is pretty much what it should be.

We probably already have support for it

Hahaha 😅

may be we need a more definitive guide to using graphql throughout an app.

1000 x this

the arguments thing is also new to me :P the relay docs are so...sparse.

Here's a simple repo to reproduce the issue with: https://github.com/simonyiszk/schdesign-web/tree/09547acbc92a6e95be4863229aa4e576022f4e4b

When using yarn develop for the first time _(without a pre-existent cache)_, the following happens:

image

There are 2 StaticQuery components on the site, one inside the Layout component and one inside the Header (which is used by Layout).

The StaticQuery inside Header runs only after src/pages/index.jsx gets updated and saved in development mode:

image

@kripod We have exactly this issue. On the first render, neither of our StaticQuerys (Nav and Footer) run. If either component is updated or saved then everything is re-rendered correctly. This means we can get the site to render locally with gatsby develop. Unfortunately, gatsby build fails completely due to these components having no data.

Apart from this issue, this is a hugely welcomed update and the rest of the v2 upgrade was very smooth!

i face the same issue (i guess), uh i started this project using the gatsby-starter-cara so not a migration in this case
and lately, not sure when this started to pop up i get this one when trying to gatsby build

Error: ./src/components/MainLayout.js 6:7
  Module parse failed: Identifier 'staticQueryData' has already been declared (6:7)
  You may need an appropriate loader to handle this file type.
  | import "core-js/modules/es6.array.find";
  | import staticQueryData from "../../public/static/d/1688394913.json";
  > import staticQueryData from "../../public/static/d/1760166728.json";
  | import React from 'react';
  | import PropTypes from 'prop-types';
   @ ./src/pages/404.js 2:0-50 5:29-39
   @ ./.cache/async-requires.js
   @ ./.cache/production-app.js

but i'm having only one import and use of staticquery so far in this one file..pages use the old "normal" queries
okay i dug into it a little and it seems that it may have started when i started using staticquery :/

but as @tomjowitt said, i'm really enjoying v2 already and looking forward to more updates to then migrate my first gatsby page t to the readme list :D keep up the great work team gatsby! 👍

I'm having the same problem as @kripod

It seems like it roots from the fact that we were recommended to use a static query in the layout component and then we use them again in a component that is included in the layout itself.

In the Layout component I pull in some site information and send that through to Helmet. Then I render a Header component which _also_ uses a static query, this time to pull in the links it will use for the navbar.

Note to others having this problem, sometimes I get stuck where I can't run gatsby develop because of the error:


error UNHANDLED REJECTION


  TypeError: Cannot read property 'hash' of undefined

  - page-query-runner.js:99 staticQueries.forEach.id
    [my-default-project]/[gatsby]/dist/internal-plugins/query-runner/page-query-runner.js:99:32

  - Array.forEach

  - page-query-runner.js:96 runQueriesForPathnames
    [my-default-project]/[gatsby]/dist/internal-plugins/query-runner/page-query-runner.js:96:17

  - page-query-runner.js:32
    [my-default-project]/[gatsby]/dist/internal-plugins/query-runner/page-query-runner.js:32:9

  - Generator.next

  - index.js:302
    [my-default-project]/[gatsby]/dist/bootstrap/index.js:302:11

  - Generator.next

  - next_tick.js:131 _combinedTickCallback
    internal/process/next_tick.js:131:7

  - next_tick.js:180 process._tickCallback
    internal/process/next_tick.js:180:9

When that continues happening even after I've resolved the error deleting the .cache folder seems to help.

@KyleAMathews I seemed to have worked around this by bringing the Head component one layer down in my Layout, so that way the structure is like

Below is the structure of what I have, but it still doesn't work with this setup, seems kind of random. Sometimes it shows the loading message and other times it doesn't. I can get it to go away sometimes by deleting the cache and sometimes I can. Does anyone know the exact conditions on when/how we are allowed to use a static query?


                                    <Layout>indexPage</Layout>

                                       +-------------------+
                                       |      Layout       |
                                       +---------+---------+
                                                 |
                                                 |
                                                 |
                                       +---------+---------+
                                       |                   |
                                +------v-------+   +-------v--------+
                                |              |   |                |
                                |     Head     |   |     Header     |
                                | (has Helmet) |   | generated nav  |
                                |              |   |                |
                                +--------------+   +----------------+

Does that mean that I can use Static Queries in as many components as I want as long as there are no nested static queries and no static queries at a higher level in the tree? Or what exactly are the conditions here...

I'm having the same issue, but this makes me wonder, what exactly is the purpose of a static query component? Unless I totally misunderstand, gatsby uses graphql to fetch data at build time, then creates static pages from this.

I want query component so that I can pass data from react client-side (at runtime) and modify the results of the query, but this is not possible with gatsby. So again, what is design purpose of ?

@KyleAMathews

Yeah, each page or component can only have one query. Pages with the same page queries from v1 and regular components with StaticQuery.

So am I to understand that StaticQuery is used inside a component for loading static data into that particular component, outside of the top-level pageQuery? Does this mean that we should not use StaticQuery as a replacement for pageQuery?

Yeah, each page or component can only have one query. Pages with the same page queries from v1 and regular components with StaticQuery.

I'm using StaticQuery in a sidebar component to show my latest blog posts and a v1 page query in the main section to show all posts. Does that mean I'm making one too many queries simultaneously since I'm also experiencing this issue?

@kripod I tried your example with beta 16 and it looks to be working now. Want to give it another try?

@KevinMind You should still use page queries in your pages, static queries can be used in components. Check out the new StaticQuery docs page for more info. Would love to see a PR if there's anything in there that's not clear.

@naheller Gatsby v2.beta-16 was released a few hours ago which should fix some issues with StaticQuery (see #6256). Can you try updating to that and see if your error is fixed?

beta-16 seems to fix my "already declared" https://github.com/gatsbyjs/gatsby/issues/5473#issuecomment-399726853 problem as described above, but now i'm getting graphql is not defined even though i'm explicitly importing it from gatsby

@m-allanson That did the trick! Thanks for all your hard work!

@CanRau hmm that sounds like a different problem? Want to create a new issue for it?

@naheller Thanks go to @pieh for doing the hard work on this one :)

@m-allanson Unfortunately this problem has come back. My first run of develop mode after upgrading to beta-16 worked fine, but the rest have shown Loading (StaticQuery) again and will only reappear once I change some data in the render output of StaticQuery.

@m-allanson Thanks for notifying me, but unfortunately, the issue still occurs once in a while after executing yarn develop multiple times e.g. after adding some extra YAML source files.

There is more PRs with fixes to come (just not sure if I'm currently fixing problem that You are experiencing). It would be very helpful if you would be able to reliably reproduce this problem and describe steps needed to do so.

Now seeing this error message when running gatsby develop:
Error loading a result for the StaticQuery in "/Users/nate/Projects/myProject/src/components/sidebar.js". Query was not run and no cached result was found.

Changing any value in the render output of sidebar.js causes Loading (StaticQuery) to disappear and the sidebar to render properly.

I wouldn't be surprised if this issue can be reproduced by attempting to execute a StaticQuery and one or more other GraphQL queries simultaneously -- for example, a sidebar component and a blog index.

@naheller This will happen right now when you edit queries when gatsby develop is not running. Saving file with static query in gatsby develop (you shouldn't even have to change anything) will trigger running query and emitting result for it, so that's why it fixes this. I have PR #6322 to fix that. Possibly there are also other issues here that I didn't identified yet - so as mentioned previously - try to figure out when this problem happen, so we can reproduce it and fix it :)

We did bunch of fixes, so just for maintance we closed this issue - if Loading (StaticQuery) will show again in newest betas, please open new issue for it, so we know there are still issues left.

@CanRau hmm that sounds like a different problem? Want to create a new issue for it?

I'm not using StaticQuery right now cause the site had to launch, beside those things I'm really happy with v2 so far, great work!
I'm trying to migrate our site over to v2, too, but have so many projects I don't know when I can proceed. I'll definitely post any issues I encounter ;-) @m-allanson

I can confirm that recent changes have fixed the issue for me. Thanks for the many updates and hard work! Really looking forward to the new version :)

Was this page helpful?
0 / 5 - 0 ratings