1

I have a Billboard component which is imported on my home page like so :

<Billboard id="successful_network_ebook_billboard"/>

The content of the component is :

import React, {Component} from "react";
import T from 'i18n-react'
import Link from "../components/LocalizedLink";
import Tank from "../components/Tank";
import CTA from "../components/CTA";
import Img from "gatsby-image"
import {graphql} from "gatsby"

import "../styles/css/components/Billboard.css";

class Billboard extends Component {
    successful_network_ebook_billboard = () => {
        return (
            <section id={this.props.id} className="Billboard">
                <Img className="bg" fluid={this.props.data.bgNetwork.childImageSharp.fluid} alt={this.props.alt}/>
                <Tank className="content">
                    <div className="text">
                        <h3>Title</h3>
                        <p>Paragraph</p>
                        <CTA to="/page">Click here</CTA>
                    </div>
                </Tank>
            </section>
        )
    }

    render() {
        switch (this.props.id) {
            /* There are more cases */
            case "successful_network_ebook_billboard":
                return (this.successful_network_ebook_billboard());
            default:
                return (
                    <div></div>
                )
        }
    }
}

export default Billboard

require("../queries/fragment.headers");

export const queryBillboardImages = graphql `
    query BillboardImages {
        bgNetwork: file(relativePath: { eq: "assets/images/healthcare/banner_soc2_bg.jpg" }) {
            ...fluidHeader
        }
    }
`

When I run the code, everything loads fine, except the image I'm trying to load via GraphQL. I get the message :

(Billboard, ) TypeError: Cannot read property 'bgNetwork' of undefined

Clearly "data" is empty, but I think I'm using the syntax that's proposed everywhere.

I tried getting this.data instead of this.props.data ; I get the same error.

I tried converting the component to a const which seemed to offer a more "direct" syntax, but I got a different, more esoteric error.

I want to know how to pass the result of the GrphQL call into my component. When I do it on a page, it's as simple as destructuring this.props.data into a constant and then it's ready to use. But when inside a component it doesn't seem to work that way.

If I do a

console.log(data)

all it returns me is the id and alt props that come from the parent.

Thank you for your help !

1 Answer 1

2

graphql query can only be used for Pages and not all components. For components you need to use StaticQuery component or with useStaticQuery with the latest version of react

export default (props) => (
  <StaticQuery
    query={graphql `
      query BillboardImages {
        bgNetwork: file(relativePath: { eq: "assets/images/healthcare/banner_soc2_bg.jpg" }) {
            ...fluidHeader
        }
    }
  `}
    render={data => (
      <Billboard  {...props} data={data}/>
    )}
  />
);

or using useStaticQuery

export default (props) => {
  const data = useStaticQuery(graphql `
      query BillboardImages {
        bgNetwork: file(relativePath: { eq: "assets/images/healthcare/banner_soc2_bg.jpg" }) {
            ...fluidHeader
        }
    }
  `)

  return (
    <Billboard  {...props} data={data}/>
  )
}
Sign up to request clarification or add additional context in comments.

4 Comments

Ok here's the thing, and please let me know if I'm going about it the wrong way. My Page already has a GraphQL request, which I use to get images that are not a part of any component. So I don't necessarily want to pass the whole data object to the child (which, correct me if I'm wrong, if the method you're suggesting ?) The Billboard component would, ideally, receive only an ID, and be able to extrapolate from there what image it needs to use from its own GraphQL request. Does your code still apply ?
@LeKevoid , what I am suggesting is that you cannot have queries like you write for components. For the Billboard component, you need to make use of StaticQuery to run whatever query you like. What I suggested was that you do not export Billboard as a default rather than that export the component which calls StaticQuery and returns that result to Billboard
Thank you ! The <StaticQuery> element has an "input" of query={} that contains the GraphQL query you want to run, and returns the render={(data} => ()}. This worked for me. Thanks so much for your help !
Glad to have helped :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.