Render props pattern in React
Tags: react, javascript, designpatterns
Published: 2018-09-10 20:26:52

---
title: Render props pattern in React
published: true
description: 
tags: react, javascript, design patterns
---



Render props is a pattern popularized by Michael Jackson of reacttraining.com and Kent C. Dodds of Paypal among others. We can see this pattern being used more and more in React itself and it's ecosystem (Context API, React Router, Apollo Client, react-motion, Downshift etc.).

## When would you use this pattern?

This pattern should be used when you are building a component that it's not concerned with rendering but it has some important business logic to do for your app. In this way you can reuse this component for business logic (fetching data, doing calculations etc.).

## Example

```react
// component that implements render prop
import React from 'react';
import PropTypes from 'prop-types';

import { fetchPosts } from './api';

class FetchPosts extends React.Component {
  static propTypes = {
    children: PropTypes.func
  };

  state = { articles: [], loading: false };

  async componentDidMount() {
    this.setState({ loading: true });

    const articles = await fetchPosts();

    this.setState({ articles, loading: false });  
  }

  render() {
    return this.props.children({articles: this.state.articles});
  }
}

// component that is using render prop component
import React from 'react';

import FetchPosts from './FetchPosts';

const ArticleList = props => {
  return (
    <FetchPosts>
      {({ loading, articles }) => {
        if (loading) {
          return 'Loading...';
        }

        return articles.map(article => <ArticleListItem article />);
      }}
    </FetchPosts>
  );
};
```

In our example we have a component that is used only for fetching data and it leaves rendering to children passed as a prop (hence the name render props). `ArticleList` component is using that data to render a list of articles. We could have a different component to render a grid list of articles that gets data from our `FetchPosts` component.

## Example from the community

### React's Context API

Let's take a look at React's context API example:

```react
import React from 'react';

const state = {
  counter: 0

const { Provider, Consumer } = React.createContext(state);

const App = props => {
  return (
    <Provider value={state}>
      <Counter />
    </Provider>
  );
}

export default App;
export { Consumer };

// Counter.js
import React from 'react';

import {Consumer} from './App';

const Counter = props => {
  return (
    // render props used here
    <Consumer>
      {state => (
        <p>{state.counter}</p>
      )}
    </Consumer>
  );
}
```

In our App component we are creating new context with `React.createContext` and we are passing default value for our context. `Provider` component is used to set the value which will be provided to a component that requests that value. 

In our `Counter` component we are using `Consumer` component that was created as a result of `createContext`'s invocation and that component is implementing render props pattern. Children of `Consumer` component is a function which is called with value that is provided as a prop to `Provider` component.

### React router Route component

React router is one of the most commonly used packages from React community. It also implements render props pattern (it's not using children as a function but it's using `render` prop). Example incoming:

```react
import React from 'react';
import {BrowserRouter as Router, Route} from 'react-router-dom';

const App = props => {
  return (
    <Router>
      <Route path='/posts' render={(props) => (// ...do something with props and render to UI)} />
    </Router>
  );
}

```
As you can see `Route` component accepts `render` props which is a function which gets props (history, location, match etc.)

### Apollo client's Query component
Apollo client implementation for React uses render props in it's `Query` component. Example of usage:

```react
import React from 'react';
import {Query} from 'react-apollo';

const App = props => {
  return (
    <Query query={POSTS_QUERY} variables={variables}>
      {({data, loading, error, fetchMore}) => {
        if (loading) {
          return 'Loading...';
        }

        if (error) {
          return error;
        }

        return <ArticleList data={data} />
      }}
    </Query>
  );
};
```

This example is a bit more complex regarding data that's returned from render prop. When `Query` component is rendering it's children it's passing an object that has decent number of properties that we can use. It's a general rule that your function accepts only one parameter and that you are destructuring properties when implementing function. But you don't have to do it, it's still a function and you can implement it however you want it.


## Conclusion

In my opinion and experience using React every day I find that render props is greatly used pattern that suites React's component composition pattern perfectly. I encourage you to think about how you can use this pattern in your code to make it more readable and reusable. Also, please share your usages of this pattern in the comments 👇 Thanks for reading 😄