DEV Community

Aakash Srivastav
Aakash Srivastav

Posted on

Render Props in React

What is Render Prop?
A render prop is a prop that is a function that renders something – i.e. a function that returns JSX.

As we know , we can pass data to child components from parent components.The child components capture the data in the props object argument.

class Fruits extends React.Component {
    constructor(props) { }
    render() {
        return <div>{this.props.name}</div>
    }
}
<Fruits name="Mango" />

Objects, arrays, booleans, strings, Numbers can be passed to child components via props. The child component uses the props argument to know what to render.

Passing an object via props:

<Fruits obj={ { name: "Mango" } } />
class Fruits extends React.Component {
    constructor(props) { }
    render() {
        return (
            <div>
                Fruit: {this.props.obj.name}
            </div>
        )
    }
}

Now, we can pass a function to the props object.

class Fruits extends React.Component {
    constructor(props) { }
    render() {
        return <div>{this.props.render()}</div>
    }
}
<Fruits render={() => [ "Mango", "Pineapple" ]} />

You see we passed a function () => [ "Mango", "Pineapple" ] to Fruits via render,then it can access it by referencing it as key in the props argument: this.props.render.
This props render bearing a function value is called a render props.

The function if a little bit complex, it is the same thing as this:

function() {
    return [ "Mango", "Pineapple" ]
}

It just returns an array. Hope the above will be clearer.

The Fruits gets the function through this.props.render and calls the function.

render() {
        return (
            <div>
                {this.props.name()}
            </div>
        )
    }

This will render the array containing fruit names:

Mango Pineapple

We actually used the render prop(a function prop) to know what to render. The render prop here is called the render prop.

So we can define a Render Prop as a function props that is used by a component to know what to render.

The render prop can return a HTML markup:

<Fruits render={()=><h1>Pineapple</h1>} />

Using Props Other Than render

It’s important to remember that just because the pattern is called “render props” you don’t have to use a prop named render to use this pattern. In fact, any prop that is a function that a component uses to know what to render is technically a “render prop”.

We can rewrite our Fruits example:

class Fruits extends React.Component {
    constructor(props) { }
    render() {
        return <div>{this.props.render()}</div>
    }
}
<Fruits render={() => [ "Mango", "Pineapple" ]} />

to use a different name other than render:

class Fruits extends React.Component {
    constructor(props) { }
    render() {
        return <div>{this.props.name()}</div>
    }
}
<Fruits name={() => [ "Mango", "Pineapple" ]} />

Props inside an Element

Following traditon, Whenever we want to pass props to child components we normally use the “attributes” like this:

<Fruits name={() => [ "Mango", "Pineapple" ]} />

Now, according to Reactjs Blog, we can actually put the props attributes inside the JSX element:

<Fruits>
    {() => [ "Mango", "Pineapple" ]}
</Fruits>

Noticed anything? The name props is no longer there. The render prop () => [ "Mango", "Pineapple" ] is now a child component to <Fruits>, it will be passed to <Fruits> in children props.

To access the render prop () => [ "Mango", "Pineapple" ], we do this this.props.children.

class Fruits extends React.Component {
    constructor(props) { }
    render() {
        return <div>{this.props.children()}</div>
    }
}
<Fruits>
    {() => [ "Mango", "Pineapple" ]}
</Fruits>

Take-aways

  1. render prop is used for sharing code between components.
  2. Every higher order component can be re-created using render props.
  3. render prop makes it possible to write reusable components.

If you have any question regarding this or anything I should add, correct or remove, feel free to comment, email or DM me. Thanks !!!

Top comments (0)