skip to Main Content

I have parent component as below:

import React from "react"
import PropTypes from "prop-types"
import Header from "./header"
import "./layout.css"
import TopBar from "./topbar"
import Bottom from "./bottom"

const Layout = ({ children, isMobile = false }) => {
  const mainStyle = !isMobile ? ".main-desktop" : ".main-mobile"
  //children.isMobile = isMobile

  return (
    <>
      <Header siteTitle={'MAIN TITLE'}
        moto={'SLOGAN.'}
        isMobile={isMobile} />
      <TopBar isMobile={isMobile} />
      <div
        style={{
          margin: `0 auto 0 auto`,
          minHeight: `50%`,
          padding: `0 1.0875rem 1.45rem`,
          paddingLeft: "90px"
        }}
      >
        <main className={mainStyle}>{children}</main>
        <br />
        <br />
      </div>
      <Bottom isMobile={isMobile} />
    </>
  )
}

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

export default Layout

I have a child component as below:

import React from "react"
import SEO from "../components/seo"

const ContactUsPage = ({ isMobile = false }) => (
    <>
        <SEO title="Contact Us"
    </>
)

export default ContactUsPage

ContactUsPage is being called inside Layout by the Gatsby framework into children variable. Now, I want to pass isMobile property from Layout. I tried setting it directly but is giving error that object is not extensible.
What is the way and if possible, what is the correct way to set the property for variable components?

2

Answers


  1. In return in the parent component:

    <ContactUsPage isMobile={isMobile} />
    

    And inside ContactUsPage component:

    const ContactUsPage = ({ isMobile }) => {
      return (
        <div>
        </div>
      );
    };
    
    Login or Signup to reply.
  2. I think you can do this in two way, the Gatsby way and the React Context way:

    The Gatsby way:

    Gatsby allows you to pass a state prop to its <Link/> component.
    The value of the state can then be retrieved from the page component (that automatically receives a location prop. See the Gatsby documentation

    The Context way:

    Create a React context that holds the isMobile value and a Component Provider:

    export const MobileContext = React.createContext({ isMobile: false });
    
    export MobileProvider = ({ children }) => {
      const [isMobile, setIsMobile] = useState(false);
    
      // Define your logic to check if it is mobile or not
    
      const value = useMemo(() => ({ isMobile }), [isMobile]);
    
      return (
        <MobileContext.Provider value={value}>
          {children}
        </MobileContext.Provider>
      )
    }
    

    And wrap your layout with that.

    Then you can access the context value on all Layout children (and their children too) with const { isMobile } = useContext(MobileContext);.
    Check the React context documentation

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search