Setting a state on the layout using gatsby const Layout = ({ children }) => ( MIND BLOWN!)

Hi I’ve spent far to much time today trying to figure this out!
I’m rebuilding my site using Gatbsy and learning about all the new bits and pieces I have recently built my site in React which went well. However, my issue seems simple (4 hours ago) I want to pass a state into the react app the access it in two separate components.

Here is what I used to use

class HomePage extends Component {
  constructor() {
    super();
    this.state = {
      loading: true,
      data: [],
      isToggleOn: false
    };
  }

  toggleShowModal() {
    this.setState({ showModal: !this.state.showModal });
  }

  componentDidMount() {
    axios
      .get(
        "https://www.stevefurley.co.uk/wordpress_site/wp-json/wp/v2/pages/121"
      )
      .then(response => {
        this.setState(() => {
          return {
            data: response.data,
            loading: false
          };
        });
      });
  }
  render() {
    const { loading, data } = this.state;
    if (loading) {
      return <Loader />;
    }

    return (
      <section className="main-container" id="content">
        <AboutMe jsonData={this.state.data} />

But as Gatsby uses this I can’t find any way to pass a state down to components? as soon as I add a constructor outside of const layout it goes bang. Any help would really be appreciated.


const Layout = ({ children }) => (
  <StaticQuery
    query={graphql`
      query SiteTitleQuery {
        site {
          siteMetadata {
            title
          }
        }
      }
    `}
    render={data => (
      <>
        <MobileMenu menuOpen={this would be the state}/>
        <Header siteTitle={data.site.siteMetadata.title} menuOpen={this would be the state} />

        <div
          style={{
            margin: `0 auto`,

This thread looks relevant.

Thanks, unfortunately I have already tried that method and as soon as I added the StaticQuery gatsby rejected it, and didn’t seem to process it. I’ll have another look now and see pop what the error on here.

I have just tried adding it theres something (I imagine something simple) that i’m missing and how to go from StaticQuery to the code. Any help would be really appreciated.


import React from "react"
import PropTypes from "prop-types"
import { StaticQuery, graphql } from "gatsby"
import MobileMenu from "../components/mobileMenu"
import Header from "../components/header"

import "../styles/main.scss"

if (typeof window !== "undefined") {
  // eslint-disable-next-line global-require
  require("smooth-scroll")('a[href*="#"]')
}




class Layout extends React.Component  {
  constructor(props) {
    super(props);
    this.state = { showMenu: true };
  }
  
  toggleMenu() {
    this.setState(prevState => { showMenu: !prevState.showMenu })
  }

  render() {
    const { children, data } = this.props;
    return (
  <StaticQuery
    query={graphql`
      query SiteTitleQuery {
        site {
          siteMetadata {
            title
          }
        }
      }
    `}
      <div>
        <MobileMenu />
        <Header siteTitle={data.site.siteMetadata.title} />

        <div
          style={{
            margin: `0 auto`,
            maxWidth: 960,
            padding: `0px 1.0875rem 1.45rem`,
            paddingTop: 0,
          }}
        >
          <main>{children}</main>
          <footer>
            © {new Date().getFullYear()}, Built with footer here as main
            {` `}
            <a href="https://www.gatsbyjs.org">Gatsby</a>
          </footer>
        </div>
        </div>
  />
)
        }
      }

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default Layout

Anyone have any ideas?

You need to make sure to receive data from the query you made through graphql using render method.

Take a look at my code that I wrote before.

You legend that that got me along the right lines I had to convert it to a class to pass the menu state through a mobile menu and header component but now have that bit working.
Thanks for your help very much appreciated.
Just in case anyone else needs this whilst using Gatbsy here’s my example

/**
 * Layout component that queries for data
 * with Gatsby's StaticQuery component
 *
 * See: https://www.gatsbyjs.org/docs/static-query/
 */
import React, { Component } from "react"
import PropTypes from "prop-types"
import { StaticQuery, graphql } from "gatsby"
import MobileMenu from "../components/mobileMenu"
import Header from "../components/header"

import "../styles/main.scss"

if (typeof window !== "undefined") {
  // eslint-disable-next-line global-require
  require("smooth-scroll")('a[href*="#"]')
}

class Layout extends Component {
  constructor() {
    super()
    this.state = {
      showMenu: false,
    }
  }

  toggleShowMenu() {
    this.setState({ showMenu: !this.state.showMenu })
  }

  render() {
    const children = this.props.children
    //const MenuState = this.state.showMenu
    console.log(this)
    return (
      <StaticQuery
        query={graphql`
          query SiteTitleQuery {
            site {
              siteMetadata {
                title
              }
            }
          }
        `}
        render={data => (
          <>
            <MobileMenu callbackFromParent={this.toggleShowMenu.bind(this)} />
            <Header
              siteTitle={data.site.siteMetadata.title}
              callbackFromParent={this.state.showMenu}
            />

            <div
              style={{
                margin: `0 auto`,
                maxWidth: 960,
                padding: `0px 1.0875rem 1.45rem`,
                paddingTop: 0,
              }}
            >
              <main>{children}</main>
              <footer>
                © {new Date().getFullYear()}, Built with footer here as main
                {` `}
                <a href="https://www.gatsbyjs.org">Gatsby</a>
              </footer>
            </div>
          </>
        )}
      />
    )
  }
}

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default Layout