An Advanced React Pattern - A HOC & Render Props
Higher Order Components and Render Props in React
When you are writing a new App or Software, It's very essential to pin down the overall details and architecture even if it's only high level, It helps to determine the shape and scalability of any software. Design pattern helps us to do exactly the same job. It's fairly common and popular. React also has its own set of design patterns which aid in writing clean and robust code while keeping it maintainable. We will discuss a couple of design patterns such as Higher Order Component (HOC) and Render Props.
Let's dive into it.
Render Props:
Render Props is one of the hottest topics in React community. As per the React official documentation.
The term "render prop" refers to the technique of sharing code between components using a prop whose value is a function.
Pretty simple, Ha? No worries. In simple words, render props are simply props where you can pass a function and that function should return an element which will be used in rendering the components.
It can be further explained with the help of one use case or example as follows:
class PersonWrapper extends React.Component {
state = {
name: 'Shubham Mathur'
};
render() {
return this.props.render(this.state.name);
}
}
const Name = () => (
<PersonWrapper render={name => <h2>Hi, {name}!</h2>} />
In the above example, the PersonWrapper component doesn't have its own rendering logic or implementation on the contrary it's being controlled from outside using render prop in the Name component. That's the beauty of the Render Props design pattern. In the above use case, the PersonWrapper component may have a complex state object and different elements to render based on that state, so instead of writing complex rendering logic we can outsource the entire rendering functionality using Render Prop, and it can be utilized as per requirements in different locations in our app.
For Example, let's say at some other location in our App the same PersonWrapper Component is required but with different rendering logic. So instead of rewriting the PersonWrapper Component logic, we could opt for the Render Prop pattern, and it can be implemented as below:
class PersonWrapper extends React.Component {
state = {
name: 'Shubham Mathur',
...,
};
render() {
return this.props.render(this.state.name);
}
}
const SomeOtherComponent = () => (
state = {
date: <some-date>,
....,
}
<PersonWrapper render={name => <h2>Hey, {name}! Your package is ready to be shipped and will reach you by {this.state.date} </h2> } />
);
So that's how we use Render Props. Pretty cool, yeah? Wait until you check out the other very popular design pattern for React - HOC (Higher Order Component).
Higher Order Component (HOC):
Higher Order Component (HOC) is another design pattern for code reusability. HOC is an advanced technique in React for reusing Component logic. HOC is not React's native API, but it emerges from React's compositional nature.
A Higher Order Component (HOC) is a function which takes a component as an argument and retuns a new component.
It's a very common and popular design pattern, and you must have used it somewhere knowingly or unknowingly such as with the Routing component or Redux.
A custom HOC is an excellent way to Abstract and Share common logic or code with different components. We can understand this with very basic and simple examples as below:
Scenario:
Let’s assume we are building an App, and it's a single-page app with multiple routes or page components that share a specific layout (HTML). Now one way to achieve it is to add that specific layout such as Header and Footer to each Page level component, or We can opt for HOC to implement this once and share it among all other components.
Layout.js
import React from 'react';
import Navigation from '../Navigation/Navigation';
import Meta from '../Head/Meta';
import Footer from '../Footer/Footer';
const navStyle = {
position: 'sticky',
top: 0,
background: '#000',
zIndex: 2
}
const layout = (props) => {
return (
<React.Fragment>
<head>
<Meta title={props.title} meta_description={props.meta_description} url={props.url} />
</head>
<nav><Navigation /></nav>
<main>
{props.children}
</main>
<Footer />
</React.Fragment>
);
}
export default layout;
Above is the very basic Page Layout Component. Here we can see that we have the liberty to provide dynamic values or props for each page as per the context, but the rendering logic is the same.
Index.js:
import Layout from './HOC/Layout';
const Index = props => (
return (
<Layout { ...props } >
{ .... }
</Layout>
);
);
export default Index;
As per the above code block, we can use HOC in our App and utilize its full potential and avoid cluttering and code duplication.
There are a lot of other use cases for both Render Props and HOC for React. One is free to use them as per their requirements.
Hope that helps to clear some fundamentals.
Cheers!
Happy Coding!