page/static graphql query becomes empty after page navigation

Viewed 233

on gatsby project, i have static query in one of my components, it gets an array of objects. Then i take window width and subdivide that array on amount of chunks i can display per screen...

that's the query:

  const { data } = useStaticQuery(graphql`
    query AutomobilesQuery {
      data: allStrapiAutomobiles(sort: { fields: created_at, order: ASC }) {
        nodes {
          id
          slug
          title
          years
          description {
            id
          }
          thumbnail {
            localFile {
              childImageSharp {
                fluid(maxWidth: 1920, quality: 100) {
                  ...GatsbyImageSharpFluid_noBase64
                }
              }
            }
          }
        }
      }
    }
  `)

size:

const size = Math.min(4, Math.ceil(width / 454))

So the first option was

const groups = chunkArray(data.nodes, size)

After window resize event data.nodes becomes empty array....

then i did it like that:

const [groups, setGroups] = useState(chunkArray(data.nodes, size))
  useEffect(() => {
    setGroups(chunkArray(groups.flat(1), size)
  }, [size])

now it does work after window resize event, but now if i navigate between local pages, data.nodes becomes empty array again...

The question is what can cause such behavior?

this array is around 30 items, maybe that due to size of the array? i did test with page query, but it has same behavior...

Hardly even have anything to guess... description.id is null on some items...

// UPDATE So code switch to page query

index.js

const index = ({ location, data }) => {
    <Layout>
      <SEO />
      ...
      <Autos automobiles={data.automobiles}/>
      ...
    </Layout>
  )
}
export const query = graphql`
  query allAutomobilesThumbsQuery {
    automobiles: allStrapiAutomobiles(sort: { fields: created_at, order: ASC }) {
      nodes {
        id
        slug
        title
        years
        description {
          id
        }
        thumbnail {
          localFile {
            childImageSharp {
              fluid(maxWidth: 1920, quality: 100) {
                ...GatsbyImageSharpFluid_noBase64
              }
            }
          }
        }
      }
    }
  }
`
export default index

component code

const Autos = ({automobiles}) => {

  const { width } = useDisplayDetect()
  const size = Math.min(4, Math.ceil(width / 454))
  const [groups, setGroups] = useState(chunkArray(automobiles.nodes, size > 1 ? size * 2 : size))

  useEffect(() => {
    setGroups(chunkArray(groups.flat(1), size > 1 ? size * 2 : size))
  }, [width])

return (
  ...
  )
}
export default Autos

same behavior, first load everything ok, then data, automobiles.nodes empty array That's after page refresh or page load:

enter image description here

That's after navigation...

enter image description here

1 Answers

Use a page query instead of static query, you can check for the differences between them in this article.

import React, {useEffect, useState} from 'react'
import { graphql } from 'gatsby'

const YourPage = ({data}) => {
  // your stuff
  const [groups, setGroups] = useState(chunkArray(data.nodes, size))
    useEffect(() => {
      setGroups(chunkArray(groups.flat(1), size)
  }, [size])

  return (
    <div>
    I'm YourPage
    </div>
  )
}

export const query = graphql`
    query AutomobilesQuery {
      data: allStrapiAutomobiles(sort: { fields: created_at, order: ASC }) {
        nodes {
          id
          slug
          title
          years
          description {
            id
          }
          thumbnail {
            localFile {
              childImageSharp {
                fluid(maxWidth: 1920, quality: 100) {
                  ...GatsbyImageSharpFluid_noBase64
                }
              }
            }
          }
        }
      }
    }
`

export default YourPage

Be aware that page queries must be used in the top-level component (pages) (but you can down pass it as you wish to any child component), this will ensure the scope of the data and will avoid inappropriate use of the useStatic hook (making unwanted triggers on every page refresh or router change). Keep also in mind to check for the window availability before making some calculations, depending on the approach this may prevent the re-hydration of the component (your related issue).

Related