React place child components in a parent component

Viewed 1189

I am a novice when it comes to ReactJS. I am trying to create a Page Component, that has a Navigation component and some other div's inside of it. But I want the Page Component to be a parent to the content of the page.

It would look something like this:

<Page>
    <h1>Hello World</h1>
    <p>This is the page content</p>
    <DummyChildComponent />
    ...
</Page>

I know I could probably pass the page contents in as a prop, but that feels wrong.

Is there a way to pass the page contents between the parent component?

Many Thanks!

3 Answers

I know I could probably pass the page contents in as a prop, but that feels wrong.

The most common solution would be to use props.children property and it is a content passed like this: <Tag>{content}</Tag>:

const Layout = ({children}) => {
  return (
    <>
      <Navbar />
      {children}
      <Footer />
    </>
  )
}

Then you can in page component use it like this:

const ExamplePage = () => {
 return (<Layout>
    <h2>Page content</h2>
    <p>Example content</p>
  </Layout>)
}

Gatsby is using that method by default.

There's absolutely nothing wrong about passing the contents as a prop! Not only is it fine, there even is a special prop called children specifically designed for this purpose and does exactly what you want.

If you want <Page> to be a functional component you would do it like this:

const Page = (props) => {
    return (
        <div className="myFancyClass">
            <h1>A fancy header that will be visible on every page</h1>
            {props.children}
            <p>Some extra information underneath my pretty page!</p>
        </div>
    )
}

And if you want <Page> to be a class component you would do it like this:

class Page extends React.Component {
    render() {
        return (
            <div className="myFancyClass">
                <h1>A fancy header that will be visible on every page</h1>
                {this.props.children}
                <p>Some extra information underneath my pretty page!</p>
            </div>
        )
    }
}

This should work perfectly in the example you provided

Hope this helps!

For example, you can do this with CSS-in-JS:

  • linaria
  • astroturf
  • styled components

In each libraries the syntax will be approximately the same:

import React from 'react';
import styled from 'styled-components';

export const UnstyledPage = ({ className }) => 
  (
    <div className={className}>
      // Here is your content components
    </div>
  )

const Page = styled(UnstyledPage)`
  // Here is styles for your parent Page component
`;

or:

import React from 'react';
import styled from 'styled-components';

export const Page = ({}) => 
  (
    <PageWrap>
      // Here is your content components
    </PageWrap>
  )

const PageWrap = styled.div`
  // Here is styles for your parent Page component
`;

Or any of these examples with children prop:

import React from 'react';
import styled from 'styled-components';

export const Page = ({ children }) => 
  (
    <PageWrap>
      { children }
    </PageWrap>
  )

const PageWrap = styled.div`
  // Here is styles for your parent Page component
`;
Related