22

I am trying to pass a wrapper component as props. Is something like this technically possible in React?

import React, {Component, PropTypes} from 'react';
import ChildComp from './child-comp';

class Comp extends Component {
  render() {
    const { Wrapper } = this.props;
    return (
      <Wrapper>
        <ChildComp />
      </Wrapper>
    );
  }
}

Comp.propTypes = {};

export default Comp;
Shota
  • 6,910
  • 9
  • 37
  • 67
  • 1
    Props Proxy [Higher order components](https://medium.com/@franleplant/react-higher-order-components-in-depth-cf9032ee6c3e#.aosc7lsuy) may be what you are looking for. Basically a wrapping function that passing the component around. – Martin Dawson Dec 23 '16 at 10:02
  • HOC Documentation: http://stackoverflow.com/documentation/reactjs/1185/components/4649/creating-components#t=20161223100405611594 – Davin Tryon Dec 23 '16 at 10:05
  • Does this answer your question? [How to pass in a react component into another react component to transclude the first component's content?](https://stackoverflow.com/questions/25797048/how-to-pass-in-a-react-component-into-another-react-component-to-transclude-the) – Michael Freidgeim May 01 '20 at 13:51

3 Answers3

50

Yes, it is perfectly possible, and commonly used. The only thing is, as a convention, in JSX capitalized words mean a user defined component, so you'll need to have your properties lowercased and you must capitalize the variable used to hold the component's reference.

import React from 'react';

function HelloWorld () {
  return (
    <span>
      <Foo wrapper={Bar}/>
      <Foo wrapper="h5"/>
    </span>
  );
}

class Bar extends  React.Component {
  render() {
    return <h1>{this.props.children}</h1>
  }
}

class Foo extends React.Component {
  render() {
    // the variable name must be capitalized
    const Wrapper = this.props.wrapper;
    return (
      <Wrapper><p>This works!</p></Wrapper>
    );
  }
}

For native components you can pass a String, like so: <Foo wrapper="h1"/>. This works because JSX is just a syntax sugar for React.createElement('h1',props, children)

Tiago Engel
  • 3,533
  • 1
  • 17
  • 22
1

You can wrap components in a number of ways. However, the most common are:

  1. Render children

When rendering children, the jsx explicitly uses the wrapping component:

<Wrapper>
  <Child />
</Wrapper>

and the Wrapper component looks like:

export default class Wrapper extends Component {
  render() {
    return (
      <div>
         { this.props.children }
      </div>
    );
  }
}
  1. Higher order component

A higher order component (HOC), is a way to mixin functionality without necessarily changing the jsx markup. You can change the jsx, but you can also mixin functionality without changing the jsx.

Using the HOC looks like this:

const Wrapped = Wrapper(Child);

...

<Wrapped />

And the HOC itself would look like:

export default Child => class extends Component {
  render() {
    return (
      <div>
         <Child />
      </div>
    );
  }
}
Davin Tryon
  • 66,517
  • 15
  • 143
  • 132
1

https://codepen.io/keshav1706/pen/eWMZwL?editors=0010

here's a codepen for simple solution. `

class ComponentOne extends React.Component {
  render() {
    return(
      <div>
        <h1>Component One</h1>
        <div>{this.props.children}</div>
      </div>
    ) 
  }
}

class ComponentTwo extends React.Component {
  render() {
    return(
      <h4>hello</h4>
    )
  }
}
class ComponentThree extends React.Component {
  render() {
    return(
      <h4>component three</h4>
    )
  }
}
ReactDOM.render(
    <div>
      <ComponentOne> <ComponentThree/></ComponentOne>
    </div>,
  document.getElementById('root')
);

`

Mick
  • 30,759
  • 16
  • 111
  • 130
Keshav Sharma
  • 483
  • 4
  • 7