Do more with less! Using render props

14,962 reads

Before proceeding! What are render props?

If you haven’t read the excellent post about Render props by Michael Jackson, (No, not the singing one), you must give it a try before proceeding with this article.

If you are too lazy to read I can hook you up with a video (that is also included in the article)

Shamelessly quoting MJ’s article:

A render prop is a function prop that a component uses to know what to render.

More generally speaking, the idea is this: instead of “mixing in” or decorating a component to share behavior, just render a regular component with a function prop that it can use to share some state with you.

If you want more info there is even a page talking about render props in the React docs.

The term “render prop” refers to a simple technique for sharing code between React components using a prop whose value is a function.

How can I use render props to solve problems?

Let’s talk business! In this section of the article I’ll go over 2 common situations (using simple to understand examples) in apps that can be adapted to any of your requirements!

In the end you will understand how the render props pattern can make our lives easier.

The repetitive data fetching on lists

I’m sure we’ve all had that use-case where you have a list or a table that fetches data from your API, while it’s fetching you show a loading indicator with a nice animation and when it finally finishes it’s job, you render the list.

Imagine that list was for Cars. How would that go? Maybe something like this:

Now imagine this propagated in an entire app with 10 or more lists. It gets tiring fast always typing that loading boilerplate, right? Now add pagination, sorting and filtering and you’ll probably go nuts quickly.

Render props is here to help. Using the pattern we quickly can make a simple List component that fetches an url and handles the loading state of a list for us.

It’s really this simple. If all your lists have common JSX templating you can even add it in this component taking out another form of repetition. Just by looking at the code you can easily assess that you can modify it to fit whatever needs you have.

Adding pagination, sorting, filtering and even a refresh button are simple features to add. Go nuts!

easy to just DO IT with render props

Now all we have to do is just use our component in our App and we’re good to go.

Take a look at the CodeSandbox below to see how it is done and maybe fiddle around with it.

The repetitive form posting to server

Here’s a little bit more complicated example. Forms are the bread and butter of most applications. It’s important to handle forms correctly to make sure everything works as intended.

Let’s imagine a situation where you have about 10 forms in your app. All of them POST to the server, while they are POSTing the submit button shows a loading indicator or message and it’s disabled and after it’s done you want to run some code.

How would that look like normally? I’m gonna use Formik for form handling.

By looking at the code we can easily point out that the biggest point of repetition is the POST fetch request to the server and the error handling. Form fields and validation will always change but you can have an app that always posts to the server with formData.

Now let’s do some work on it and apply render props to re-use all that yummy logic.

With little work we’ve abstracted the main point of repetition and just made our lives easier by creating the AjaxForm render prop Component.

It takes any url and even gives you an onSuccess callback. Now the long and repetive processes of adding form submition to your app is long gone.

Check the CodeSandbox below to see an example

NOTE: It does not submit anywhere (only has example url given) but you can see how it works and please feel free to tinker with it.

CodeSandbox for AjaxForm

Don’t just use these components out of the box

Premature optimization is the root of all evil

Before using (or building) these components you should first make sure your app requirements won’t change in the near future. Resist the urge to refactor early, because your requirements might change and if they do you will keep making changes to these components. With so many changes you might end up with an unmanageable piece of code.

My advice is:

Outline your requirements

Code them as you would normally

Register points of possible refactor

Make sure the requirements won’t change dramatically

Refactor away!

Make the components that fit your app and your requirements. Don’t just settle for these abstract simple examples.

Challenges

If you want to practice this neat little pattern I have some challenges for you:

Add pagination support to the List render prop Component

Add sorting support to the List render prop Component

Incorporate an ErrorBoundary in the List render prop Component to handle exceptions.

Examples of render props in the wild

These packages make use of this pattern:

Do I have to use this pattern?

Don’t like it? It’s okay. You can take a look at Higher Order Components.

Before closing

I appreciate the fact that you took the time to go through the article and I would like to leave with a question (you can answer in the comments).

Do you see yourself using this pattern? Why or Why not?

Thank you

Tags