Render Props in React
Tags: react
Published: 2019-10-30 14:16:07

**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.
```js
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**:

```js
<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.

```js
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:

```js
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.

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

This will render the array containing fruit names:

```js
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:

```js
<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:

```js
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:

```js
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:

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

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

```js
<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`.

```js
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 !!!