Pass React component as prop to render as child in another component

Written on April 12, 2022

Let’s say you’re trying to put together this button with an icon in React.

Button with poop emoji icon

You could achieve this by creating a button component like this:

function Button ({ label }) {
  return(
    <div>
      <div>💩</div>
      <div>{ label }</div>
    </div>
  )
}

But what if instead of a poop icon™ you wanted to pass a different icon for the button?

You could, of course create another button component with the different icon.

function ButtonWithDifferentIcon ({ label }) {
  return(
    <div>
      <div>🦄</div>
      <div>{ label }</div>
    </div>
  )
}

But as you can see, every time you have a new icon, you’d have to create a different button component along with it, not making it very reusable.

Instead it’d be great if we could have a single <Button /> component which we could then pass various icon components to it based on what we need.

Pass components as React props

Well it turns out you can indeed do this, by passing components as props in React.

Let’s make some changes to make this happen.

First, we’ll move the icon into its own component.

function PoopIcon () {
  return(
    <div>💩</div>
  )
}

Now, we’ll update the <Button /> component to render an icon as a prop.

function Button ({ icon, label }) {
  return(
    <div>
      { icon }
      <div>{ label }</div>
    </div>
  )
}

And here’s how we would create our original button, passing the <PoopIcon /> component now as a prop.

<Button 
  icon={ <PoopEmoji /> }
  label='Make it poop'
/>

If we had a <UnicornIcon /> component, we could easily create a <Button /> component without having to create a separate button component but by passing the icon component as a prop.

<Button
  icon={ <Unicorn /> }
  label='Pet unicorn'
/>

Which would then yield this button.

Button with unicorn emoji icon

Stay in touch

Thanks for reading this article. I'd love to stay in touch and share articles like this one in your inbox. Sign up for my newsletter.