Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save rococodogs/5c40667fc426425a7ed57ae122603d62 to your computer and use it in GitHub Desktop.

Select an option

Save rococodogs/5c40667fc426425a7ed57ae122603d62 to your computer and use it in GitHub Desktop.

So if this is our site wrapper:

function Main (props) {
  return (
  <div>
    <SiteHeader />
    {props.children}
  </div>
  )
}

To pass the props from

all the way down, we'd do something like this:

...
  <div>
    <SiteHeader/>
    {React.cloneElement(props.children, props)}
  </div>
...

What that does is clone our props.children element and provides them props passed to <Main/>.

However, I was finding that, with react-router, the components in my sub-routes were being duplicated. So I'd get something like this:

<Main>
  <SiteHeader/>
  <CollectionWrapper>
    <CollectionHeader />
    <CollectionWrapper>
      <CollectionHeader />
      <CollectionWrapper>
        ... collection data ...
      </CollectionWrapper>
    </CollectionWrapper>
  </CollectionWrapper>
</Main>

And what's worse: the sub-<CollectionWrapper/> components wouldn't have the props passed from <Main/> anymore.

The best I can/could tell, when we were cloning the children all the way up at <Main/>, we were also applying <Main/>'s children to those elements. Somehow, this ran out of steam after the third duplicate element, but when I would try and clone the props from the last occurance in the downstream, I would get stack overflow.

However, if we use React.Children.map on the top-level wrapper and pass React.cloneElement the child's children, everything seems to be fine!

So we end up with this:

function Main (props) {
  return (
  <div>
    <SiteHeader/>
    {React.Children.map(props.children, function (c) {
      return React.cloneElement(c, props, c.props.children)
    })}
  </div>
  )
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment