46

Understanding React Render Props and HOC

 5 years ago
source link: https://www.tuicool.com/articles/hit/iA3EnqQ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

If you have been doing some React development recently , you must have come across terms like HOCs and Render Props. In this article, we’ll go deep into both these pattern to understand why we need them and how we can correctly use them to build better react applications.

Why do we need these patterns?

React offers a simple method for code reuse and that is Components. A component encapsulates many things ranging from content, styles and business logic. So ideally in a single component we can have a combination of html, css and js all of which have a single purpose, a single responsibility .

Tip: Using Bit (GitHub ) you can organize and share reusable components to be discovered, shared and developed from different projects and applications. It’s faster than re-writing them or maintaining a heavy library. Give it a try :)

Example

Let’s suppose we are working on an E-commerce application. Like any E-commerce application, a user is shown all the products available, and the user can add any product to cart. We will fetch the products data from an API and show the product catalog as a list of cards.

In this case, the React component can be implemented like this:

bYrUNzr.png!web
Link to Code

For our admins, there is a management portal where they can add or remove products. In this portal we fetch the products data from the same API and show the product catalog in tabular form.

This React component can be implemented like this:

FFnaQfy.png!web
Link to Code

One thing that immediately sticks out is that both the components implement the product’s data fetching logic.

Going forward these situations might arise too.

ProductList

If we make a different component for each of these then we’ll be duplicating a lot of code.

Fetching data and showing data are two separate concerns. As said earlier, It is much better if one component has one responsibility.

Let’s refactor the first component. It will take products data as prop and render the product catalog as a list of cards just like before. Since we don’t need component state and lifecycle methods we’ll convert it to a functional component.

It will look like this now:

nQ7JFbU.png!web
ProductList.js ( Link to Code)

Just like ProductList , ProductTable will be a function component that take product data as prop and render the data as rows of table.

Now let’s make a component named ProductsData . It fetches the products data from API. The data fetching and state updating will be just like in the original ProductList component. But what should we put in the render method of this component?

NjeEryE.png!web
ProductData.js ( Link to Code)

If we simply put the ProductList component then we can’t reuse this component for ProductTable. Somehow, if this component can ask for what to render then the issue will be solved. At one place we will tell it to render the ProductList component and in the management portal we will tell it to render ProductTable component.

This is where render props and HOCs come into play. They are nothing but ways for a component to ask what should it render. This drives code reuse even further.

Now that we know why we need them, let’s see how to use them.

Render Props

Understanding Render Props at a conceptual level is very easy. Let’s forget about React for a minute and look at things in context of vanilla JavaScript.

We have a function that calculates the sum of two numbers. At first we just want to log the result to console. So, we designed the function like this:

ryuUBzE.png!web

However, we soon find out that the sum function is very useful and we need it in other places also. So, instead of logging it to console we want the sum function to provide the result only, and let the caller decide how it wants to use the result.

It can be done in this manner:

RBjYnqu.png!web
Link to Code

We pass sum function a callback function as argument fn . The sum function then calculates the result and calls fn with the result as an argument. This way the callback function gets the result and it is free to do anything with the result.

This forms the essence of render props. We will gain more clarity by using the pattern so let’s apply it to the problem we are facing right now.

Instead of a function that calculates the sum of two numbers, there is a component ProductsData that fetches products data. Now ProductsData component can be passed a function via props. The ProductsData component will then fetch products data and provide that data to the function that was passed as prop. The passed function can now do whatever it want with the products data.

In React, it can be implemented like this:

BR3UVfr.png!web
Link to Code

Just like the fn argument, we have a render prop which will be passed a function. Then the ProductData component calls this function with products data as argument.

We can thus use the ProductData component in this manner.

QZFVve7.png!web
Link to Code

As we can see render props is quite a versatile pattern. Most things can be accomplished in a very straight-forward manner. And this is exactly why we can shoot ourselves in the foot.

A simple way to avoid nesting is to break out the component into smaller components and keep these components in separate files. Another way is to make more components and compose them instead of having long functions inside render props.

Next we’ll look at another popular pattern called HOC.

Higher Order Components (HOC)

In this pattern we define a function which takes a component as an argument and then returns the same component but with some added functionality.

If that sounds familiar, that’s because it is similar to decorator pattern used extensively in Mobx. Many languages like Python have decorators in-built and JavaScript is going to support decorators soon. HOCs are very much like decorators.

Understanding HOCs with code is much easier than to explain with words. So we’ll look at the code first.

63QfIvy.png!web
Link to Code

As we can see the data fetching and state updating logic is just like what we did in render props. The only change is that the component class is inside a function. The function takes a component as argument and then inside the render method of the class we render the passed component but with additional props. Pretty simple implementation for a pattern with such a complicated name, right?

uYNNbiQ.png!web
Link to Code

So now we have looked at why we need render props, HOCs and how we can implement both of them.

One question remains: how do we choose between Render Props and HOCs? There have been quite a lot of articles on this topic so I won’t talk about that now. Maybe in my next post :)

When to NOT use Render Props — Kent C. Dodds

HOCs vs Render Props — Richard Kotze

Conclusion

In this article we looked at why we need these patterns, the essence of each pattern and how we can leverage these patterns to build highly reusable components. That’s all for now, hope you liked it, and please feel free to comment and ask anything . I’d be happy to talk :clap:

You can also follow me on Twitter and Medium or subscribe to my newsletter !


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK