Skip to content

Commit

Permalink
docs: remove TODOs from Static vs Normal Queries to focus more on int…
Browse files Browse the repository at this point in the history
…ernals (#19219)

* remove TODOs and focus the doc more on internals

* Apply suggestions from code review

Co-Authored-By: Michael <[email protected]>

* Apply suggestions from code review

Co-Authored-By: Marcy Sutton <[email protected]>

* updates to remove implementation details and clarify more concepts

* add one more example to show differences

* Apply suggestions from code review

Co-Authored-By: LB <[email protected]>

* Update docs/docs/static-vs-normal-queries.md

Co-Authored-By: LB <[email protected]>
  • Loading branch information
2 people authored and LB committed Nov 18, 2019
1 parent f50c700 commit 20afc1b
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 32 deletions.
2 changes: 1 addition & 1 deletion docs/docs/query-execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ In `develop` mode, every time a node is created, or is updated (e.g. via editing

#### Queue queries for execution

There is now a list of all pages that need to be executed (linked to their Query information). Gatsby will queue them for execution (for realz this time). A call to [runQueriesForPathnames](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/internal-plugins/query-runner/page-query-runner.js#L127) kicks off this step. For each page or static query, Gatsby creates a Query Job that looks something like:
There is now a list of all pages that need to be executed (linked to their Query information). Gatsby will queue them for execution (for real this time). A call to [runQueriesForPathnames](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/internal-plugins/query-runner/page-query-runner.js#L127) kicks off this step. For each page or static query, Gatsby creates a Query Job that looks something like:

```javascript
{
Expand Down
127 changes: 96 additions & 31 deletions docs/docs/static-vs-normal-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,21 @@
title: Static vs Normal Queries
---

> This documentation isn't up to date with the latest version of Gatsby.
>
> Outdated areas are:
>
> - describe how queries are stripped and JSON imports are rewritten
>
> You can help by making a PR to [update this documentation](https://github.com/gatsbyjs/gatsby/issues/14228).
Gatsby handles three varieties of GraphQL queries: Page queries (sometimes for simplicity referred to as "normal queries"), static queries using the `<StaticQuery />` component, and static queries using the `useStaticQuery` hook.

## How StaticQuery differs from page query
## Differences between varieties of GraphQL queries

StaticQuery can do most of the things that page query can, including fragments. The main differences are:
Static queries differ from Gatsby page queries in a number of ways. For pages, Gatsby is capable of handling queries with variables because of its awareness of page context. However, **page queries can only be made in top-level page components**.

- page queries can accept variables (via `pageContext`) but can only be added to _page_ components
- StaticQuery does not accept variables (hence the name "static"), but can be used in _any_ component, including pages
- StaticQuery does not work with raw React.createElement calls; please use JSX, e.g. `<StaticQuery />`
- _NOTE: you can also use the new `useStaticQuery` hook; more information below_
- Static Queries don't need to get run for each page.(ie:Just once)
In contrast, static queries do not take variables. This is because static queries are used inside specific components, and can appear lower in the component tree. Data fetched with a static query won't be dynamic (i.e. **they can't use variables**, hence the name "static" query), but they can be called at any level in the component tree.

## useStaticQuery hook
_For more information on the practical differences in usage between static and normal queries, refer to the guide on [static query](/docs/static-query/#how-staticquery-differs-from-page-query). This guide discusses the differences in how they are handled internally by Gatsby_

- Gatsby v2.1.0 introduces `useStaticQuery`, a Gatsby feature that allows you to use a React hook to query GraphQL
- `useStaticQuery` is a hook, contrary to `<StaticQuery />` which is a component
- Check out [how to query data at build time using `useStaticQuery`](https://www.gatsbyjs.org/docs/use-static-query/)
## Keeping track of site queries during build in Redux stores

### staticQueryComponents
Gatsby stores the queries from your site in Redux stores called `components` and `staticQueryComponents`. This process and a flowchart illustrating it are explained in the [query extraction](/docs/query-extraction/#store-queries-in-redux) guide.

Started here because they're referenced in page-query-runner:findIdsWithDataDependencies.

The redux `staticQueryComponents` is a map from component jsonName to StaticQueryObject. E.g
In Redux, `staticQueryComponents` is a `Map` from component `jsonName` to `StaticQueryObject`. An example entry in that data structure looks like this:

```javascript
{
Expand All @@ -45,18 +31,97 @@ The redux `staticQueryComponents` is a map from component jsonName to StaticQuer
}
```

The `staticQueryComponents` redux namespace is owned by the `static-query-components.js` reducer with reacts to `REPLACE_STATIC_QUERY` actions.
In the example above, `blog-2018-07-17-announcing-gatsby-preview-995` is the key, with the object as its value in the `Map`.

The `staticQueryComponents` Redux namespace watches for updates to queries while you are developing, and adds new data to your cache when queries change.

## Replacing queries with JSON imports

With the final build, there isn't a GraphQL server running to query for data. Gatsby has already [extracted](/docs/query-extraction/) and [run](/docs/query-execution/) the queries, [storing](/docs/query-execution/#save-query-results-to-redux-and-disk) them in files based on hashes in `/public/static/d/<hash>.json`. It can now remove code for GraphQL queries, because the data is already available.

It is created in query-watcher. TODO: Check other usages
### Distinguishing between static and normal queries

TODO: in query-watcher.js/handleQuery, we remove jsonName from dataDependencies. How did it get there? Why is jsonName used here, but for other dependencies, it's a path?
Babel traverses all of your source code looking for queries during query extraction. In order for Gatsby to handle static and normal queries differently, it looks for 3 specific cases in [`babel-plugin-remove-graphql-queries`](https://github.com/gatsbyjs/gatsby/blob/master/packages/babel-plugin-remove-graphql-queries/src/index.js):

### Usages
1. JSX nodes with the name `StaticQuery`
2. Calls to functions with the name `useStaticQuery`
3. Tagged template expressions using the `gql` tag

- [websocket-manager](#TODO). TODO
- [query-watcher](#TODO).
### Adding imports for page data

- `getQueriesSnapshot` returns map with snapshot of `state.staticQueryComponents`
- handleComponentsWithRemovedQueries. For each staticQueryComponent, if passed in queries doesn't include `staticQueryComponent.componentPath`. TODO: Where is StaticQueryComponent created? TODO: Where is queries passed into `handleComponentsWithRemovedQueries`?
Code that is specific for querying the GraphQL server set up during build time is no longer relevant, and can be swapped out in exchange for the JSON data that has been extracted for each query.

The imports related to GraphQL and query declarations are changed to imports for the JSON that correspond to the query result that Gatsby found when it ran the query. Consider the following component with with a static query written using the `useStaticQuery` hook:

```jsx
import { useStaticQuery, graphql } from "gatsby"

export () => {
const data = useStaticQuery(graphql`
siteMetadata {
site {
title
}
}
`)
return (
<h1>
{data.siteMetadata.site.title}
</h1>
)
}
```

This component will have the query string removed and replaced with an import for the JSON file created and named with its specific hash. The Redux stores tracking the queries link the correct data to the page they correspond to.

The above component is rewritten like this:

```diff
- import { useStaticQuery, graphql } from "gatsby"
+ import dataJson from `/d/<hash>.json`

export () => {
- const data = useStaticQuery(graphql`
- siteMetadata {
- site {
- title
- }
- }
- `)
+ const data = dataJson

return (
<h1>
{data.siteMetadata.site.title}
</h1>
)
}
```

A page query would be updated in a similar fashion. Alhough the exact specifics of what has to change are different, the idea is the same:

```diff
- import { graphql } from "gatsby"
+ import dataJson from `/d/<hash>.json`

- export const query = graphql`
- query HomePageQuery {
- site {
- siteMetadata {
- description
- }
- }
- }
- `

- export ({ data }) => {
+ export ({ data = dataJson }) => {
return (
<h1>
{data.siteMetadata.site.title}
</h1>
)
}
```

TODO: Finish above
Gatsby will remove unnecessary imports like `useStaticQuery` and `graphql` from your pages along with the strings containing queries as well.

0 comments on commit 20afc1b

Please sign in to comment.