Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impossible to declare multiple components that use <StaticQuery> in one file #9580

Closed
ukch opened this issue Oct 30, 2018 · 9 comments

Comments

Projects
None yet
9 participants
@ukch
Copy link

commented Oct 30, 2018

Description

Say I want to have multiple components in a single file, that both use StaticQuery in one form or another.

Example code:

// src/components/things.js

import React from "react";
import {StaticQuery} from "gatsby";

export const MyFirstQuery = (props) => (
    <StaticQuery query={some_query} render={() => <div>hello world</div>} />
);

export const MySecondQuery = (props) => (
    <StaticQuery query={some_query} render={() => <div>hello world</div>} />
);
// src/pages/testpage.js

import React from "react";
import { MyFirstQuery } from "../components/things";

export const () => (
    <div>
        Here is my first static query:
        <MyFirstQuery />
    </div>
);

The page will render as expected when using gatsby develop, but gatsby build will cause the following error to occur:

error Generating JavaScript bundles failed

  Error: ./src/components/things.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 _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
  | import staticQueryData from "../../public/static/d/2162154064.json";
  > import staticQueryData from "../../public/static/d/2162154064.json";
  | import { StaticQuery } from "gatsby";
   @ ./src/pages/testpage.js 2:0-47 105:31-39
   @ ./.cache/async-requires.js
   @ ./.cache/production-app.js

Steps to reproduce

  • Create a simple starter site.
  • Copy the two files above (replace some_query with any valid GraphQL query)
  • gatsby build

Expected result

The project should build. It shouldn't matter that the two StaticQuerys are in the same file.

Actual result

See the error above.

Environment

I am unable to post info due to #8502. However, I am running gatsby-cli version 2.4.4 (globally installed), and gatsby version 2.0.35.

@LekoArts

This comment has been minimized.

Copy link
Contributor

commented Dec 14, 2018

I made a reproduction repo where this behavior can be observed: https://github.com/LekoArts/two-static-repro

@mik-laj

This comment has been minimized.

Copy link

commented Jan 2, 2019

I recommend using HOC to reduce the code repetition.

// src/components/things.js

import React from "react";
import { StaticQuery } from "gatsby";

const withData = (WrappedComponent) = (
  (props) => 
    <StaticQuery query={some_query} render={(data) => 
      <WrappedComponent {...props} data={data}/>
    } />  
)

export const MyFirstQuery = withData(({data, ...props}) => (
    <div>hello world</div>
));

export const MySecondQuery = withData(({data, ...props}) => (
    <div>hello world</div>
));

But the error still in Gatsby will exist. My answer should be treated as a solution for others with this problem, until this problem is solved.

@jonniebigodes

This comment has been minimized.

Copy link
Contributor

commented Jan 2, 2019

@mik-laj Thanks for the quick fix. It will probably be helpfull for people experiencing this issue. 👍

@Coder2012

This comment has been minimized.

Copy link

commented Jan 28, 2019

@mik-laj

Thank you for your solution, I don't quite understand how to use it with multiple queries though. How does some_query get passed in to the StaticQuery?

Would you be able to show example please?

@jtran19

This comment has been minimized.

Copy link

commented Feb 10, 2019

@Coder2012 Maybe a more fleshed out example might help. I was having this issue as well and @mik-laj comment flipped on the lightbulb for me.

// src/components/image.js

function withImageData(WrappedComponent) {
  return props => (
    <StaticQuery
      query={graphql`
        query AstronautImageQuery {
          placeholderImage: file(relativePath: { eq: "gatsby-astronaut.png" }) {
            childImageSharp {
              fluid(maxWidth: 300) {
                ...GatsbyImageSharpFluid
              }
            }
          }
          logoImage: file(relativePath: { eq: "logo.png" }) {
            childImageSharp {
              resolutions {
                width
                height
                src
                srcSet
              }
            }
          }
        }
      `}
      render={data => <WrappedComponent {...props} imageData={data} />}
    />
  );
}

const Image = withImageData(props => (
  <Img fluid={props.imageData.placeholderImage.childImageSharp.fluid} />
));
const Logo = withImageData(props => (
  <Img resolutions={props.imageData.logoImage.childImageSharp.resolutions} />
));

export { Image, Logo };

With this, I can now do...

// src/testlogo.js

import { Logo } from './components/image';
export default () => <Logo />

By using GraphQL aliases, you can query for as many image files as you need to, and your wrapped components just pluck out the one(s) they need.

@anicolaides

This comment has been minimized.

Copy link

commented Feb 15, 2019

Although this is not a solution to the issue, as of Gatsby v2.1.0, useStaticQuery can be used.

Instead of using this design pattern:

import {StaticQuery, graphql } from 'gatsby'

const ImagesQ = graphql`
  fragment servicesImage on File {
    childImageSharp {
      fluid(maxWidth: 500) {
        ...GatsbyImageSharpFluid_withWebp
      }
    }
  }

  query {
    image1: file(relativePath: { eq: "entrance.jpg" }) {
      ...servicesImage
    }

    image2: file(relativePath: { eq: "students.jpg" }) {
      ...servicesImage
    }

    image3: file(relativePath: { eq: "flags.jpg" }) {
      ...servicesImage
    }

    image4: file(relativePath: { eq: "admission.jpg" }) {
      ...servicesImage
    }

    image5: file(relativePath: { eq: "support.jpg" }) {
      ...servicesImage
    }
  }
`

// Along with... multiple StaticQuery elements
const MyComponent = () => (
  <div>
    <StaticQuery
      query={ImagesQ}
      render={data => <Img fluid={data.image#.childImageSharp.fluid} />}
    />
   // blah...
</div>
)

One may use the following:

const Services = () => {
  const data = useStaticQuery(graphql`
    fragment servicesImage on File {
      childImageSharp {
        fluid(maxWidth: 500) {
          ...GatsbyImageSharpFluid_withWebp
        }
      }
    }

    query {
      image1: file(relativePath: { eq: "entrance.jpg" }) {
        ...servicesImage
      }

      image2: file(relativePath: { eq: "students.jpg" }) {
        ...servicesImage
      }

      image3: file(relativePath: { eq: "flags.jpg" }) {
        ...servicesImage
      }

      image4: file(relativePath: { eq: "admission.jpg" }) {
        ...servicesImage
      }

      image5: file(relativePath: { eq: "support.jpg" }) {
        ...servicesImage
      }
    }
  `)

  return (
    <Img fluid={data.image1.childImageSharp.fluid} />
  )}

Much cleaner as well :).

@Alfrex92

This comment has been minimized.

Copy link

commented Mar 2, 2019

thanks @anicolaides it is working :D

@gatsbot gatsbot bot added the stale? label Mar 23, 2019

@gatsbot

This comment has been minimized.

Copy link

commented Mar 23, 2019

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!

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

@gatsbot

This comment has been minimized.

Copy link

commented Apr 3, 2019

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.

Thanks again for being part of the Gatsby community!

@gatsbot gatsbot bot closed this Apr 3, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.