Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a wrapper component as props in ReactJS

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;
like image 745
Shota Avatar asked Dec 23 '16 10:12

Shota


People also ask

Can I pass a component as a prop in React?

You can pass a component as props in React by using the built-in children prop. All elements you pass between the opening and closing tags of a component get assigned to the children prop. Copied!

How do you make wrapper components in React with props?

To create wrapper components, you'll first learn to use the rest and spread operators to collect unused props to pass down to nested components. Then you'll create a component that uses the built-in children component to wrap nested components in JSX as if they were HTML elements.


2 Answers

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)

like image 77
Tiago Engel Avatar answered Sep 30 '22 18:09

Tiago Engel


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>
    );
  }
}
like image 42
Davin Tryon Avatar answered Sep 30 '22 19:09

Davin Tryon