menu
announcement

Spectrum is now read-only. Learn more about the decision in our official announcement.

Gatsby

Fast in every way that matters. Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps.

Channels
Team

Why can't a regular 'query' be used in any component? Why must 'staticQuery'…

September 19, 2018 at 7:33am

Why can't a regular 'query' be used in any component? Why must 'staticQuery' exist?

September 19, 2018 at 7:33am
So I'm learning Gatsby as of V2, but staticQuery feels a little off to me initially. I'm sure I don't understand it well in any way, but it staticQuery's API feels really odd to me, instead of just making a query in the component and then using it in the component. So many potential levels of indentation, and the co-location of things all feel very not so good to me, for lack of a better way to explain myself. I'm also brand new to react, coming from HTML, CSS and JS, so much of the ideas of react are still new to me as well.
So, I guess my question is why can't a regular query be used like staticQuery? What about Gatsby created the need for staticQuery to exist? I've read the basic articles on the site and watched a couple short videos, but I think I'm still not getting it. Why can't I simply add a query to my header component? Why won't a regular query work and thus, a staticQuery is required in a regular query's place?
Any clarification that anybody wouldn't mind sharing would be appreciated, as I'm super new to Gatsby :-)

September 19, 2018 at 12:59pm
staticQuery is following a common design pattern in the React world (render props). You can watch Michael Jackson's talk on why render props is a good pattern here: https://spectrum.chat/thread/34123b77-f331-407b-8149-d0fc16398511. apollo another massive popular graphQL framework uses the same API for its queries.
One of the benefits of having staticQuery is that you avoid prop drilling. With gatsby v1 your query had to always be in entry component (page, layout, template) and if that data was required in a component 6 levels down bellow you needed to pass it all the way down. With staticQuery you can enhance a component deep in the tree and give access to graph data without having to use props.
I hope this makes sense!
like-fill
1
Honestly, there is no reason why you can't from a technical perspective. StaticQuery was added later to address the problem of not being able to use queries anywhere. We didn't backport the same behavior to exported queries for a couple a of reasons, not the least of which is that exported queries are harder to statically extract.
If it helps you can think about StaticQuery as superseding the old API, and in some sense page queries as "deprecated" (even tho they aren't technically). You can use StaticQuery for all the same things but more flexibly, having both is more of an API wart than an intended choice.
hmmmm...in one of the videos I watched about staticQuery the speaker mentioned that static query only works with static elements, which makes sense, based on its name. So, if I have a persistent music player component in my app which will need to change it’s content based on user song selections, then staticQuery would not be the right choice for that use case? The music player component would be persistent, then on top of that, the song info, like the name, artist, album art, length, etc...would change for every new selection.
StaticQuery is functionally the same as the page query. the query in it is resolved and run at compile time so it won't update if you change it at runtime, but the same is true for page queries as well
like-fill
1
The scenario you are explaining isn't something that won't work not because of queries or staticQueries. You need live data to keep refreshing your application. That's something you won't get from a static site generator because the data gets fetch once, build on the server and then push static files to the client. If you need that you will have to do it all on the client side with React and a cloud function/API if you stick with gatsby. However, for the type of application you are describing gatsby/JAM stack isn't probably the best choice.
The main difference is that page queries have access to the page context, which can be defined during createPage in gatsby-node.js.
StaticQuery does not have access to context, so queries can't use GraphQL variables.
Otherwise, they're more or less the same thing.
Does that make sense?
like-fill
1
Oh, I missed the live update thing. For live updates you would need a different solution, such as Apollo for the front-end.
The Gatsby swag store makes async calls to a back-end from the client side for things like user auth and cart management, which is similar to the approach you might use for a music player. The source is here if you'd like to see it: https://github.com/gatsbyjs/store.gatsbyjs.org

September 21, 2018 at 9:20pm
hmmmm...ok, I’ll check out Apollo then. I’m also a little bit fuzzy on Gatsby as well, I guess. My current understanding is that it will generate your static content, like a static site generator, and then run as a react app on the client to handle dynamic content. But there is no built-in solution for dyanamic query’s, which is why something like Apollo is recommended. Please correct me if this understanding is incorrect in any way :-)

September 27, 2018 at 4:12am
hmmm...is there not a global context for persistent data and components? It feels quite odd to me to nest everything in a persistent component inside of a <StaticQuery>, where creating a regular graphQL query just feels so natural and easy. Would a global context make this API fell nicer and more logical to use? Is that something that is possible? I am speaking from a super ignorant place on this, however, so, many grains of salt with my words.