In this article, I will define a higher-order component and take a look at how to implement it by building the sidebar nav.
A higher-order component takes another component as a parameter and returns a new modified component. When you have a component that has constant elements and you want to display the variable components inside of it, the simple way is to use Higher order component (HOC).
For example:
Component(ButtonComponent) => NewComponentWithButtonComponent
Component(FormComponent) => NewComponentWithFormComponent
Component(ContactComponent) => NewComponentWithContactComponent
Let’s dissect this concept with a real-world example.
I’m going to build a sidebar nav as illustrated in the figure below.
The first step is to create a react app by typing the below command
npx create-react-app sidebarhoc
Then install react-router
npm install react-router-dom
By deleting unnecessary files the folder structure will look as below in the figure
I have modified the style a little to help us visualize what is going on. Copy this CSS code or style your own and paste it to the index.css file
.header {
height: 8vh;
display: flex;
justify-content: space-between;
background-color: rgb(134, 139, 100);
align-items: center;
padding-right: 2rem;
}
.title {
font-size: 2rem;
font-weight: bold;
padding-left: 1rem;
color: #fff;
}
.logo {
font-size: 2rem;
font-weight: bold;
padding-left: 1rem;
}
.layout {
height: 100vh;
}
.sidebar {
display: flex;
flex-direction: column;
width: 20%;
height: 95vh;
background-color: rgb(209, 209, 250);
}
.nav-link {
font-size: 1.5rem;
text-decoration: none;
color: black;
text-align: center;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
.active {
background-color: rgb(71, 71, 71);
color: white;
}
.container {
display: flex;
}
To make things simple, our app will have 3 routes which are the root route(“/”), about and contact.
Now, it’s time to create the Layout component where in this component there are two components (Header and Sidebar) that are fixed and the remaining ones vary, meaning that you can display the about or contact component.
Let us define our HOC component and name it as Laoyout.jsx
Type the following command to create the Layout component.
mkdir src/layouts
touch src/layouts/Layout.jsx
So, this Layout component is the higher order component and it should look like this
src/layouts/Layout.jsx
import Header from './Header';
import SideBar from './SideBar';
const Layout = (Component) => ({ ...props }) => (
<div className="layout">
<Header />
<div className="container">
<SideBar />
<div className="main-container">
<Component {...props} />
</div>
</div>
</div>
);
export default Layout;
The above code shows a HOC which has Header and SideBar components that are fixed and it receives the Component as a parameter, inheriting all the props.
Next, I will create the Header.jsx and SideBar.jsx inside the layouts folder by typing the following commands:
touch src/layouts/Header.jsx
touch src/layouts/SideBar.jsx
src/layouts/Header.jsx
import React from 'react'
const Header = () => {
return (
<div className="header">
<div className="logo">Logo</div>
<div className="title">
This is the header
</div>
</div>
)
}
export default Header
src/layouts/SideBar.jsx
import React from 'react'
import { NavLink } from 'react-router-dom';
const lists = [
{ name: 'Home', path: '/' },
{ name: 'About', path: '/about' },
{ name: 'Contact', path: '/contact' },
];
const SideBar = () => {
return (
<div className="sidebar">
{lists.map(list => {
return (
<NavLink to={list.path}
className={ ({isActive}) => isActive ? 'nav-link active' : 'nav-link' }
>{list.name}</NavLink>
)
})}
</div>
)
}
export default SideBar
As you can see, the above code has links that direct the user to either the home page, about page or contact page. All of which I put in the routes folder.
Now I will create the routes folder as shown below:
mkdir src/routes
touch src/routes/About.jsx
touch src/routes/Contact.jsx
Add the content of the created files:
touch src/routes/About.jsx
import React from 'react';
const About = () => (
<div>
<h1>About page</h1>
About
this page is about all available info
</div>
);
export default About;
touch src/routes/Contact.jsx
import React from 'react';
const Contact = () => (
<div>
<h1>Contact</h1>
<h3>Phone: 0737374824</h3>
</div>
);
export default Contact;
To use our Layout HOC component we need to import it into the index.js file and pass the About and Contact components as parameters. Then configure the routes as shown below in the Index.js file
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import App from './App';
import './index.css';
import Layout from './layouts/Layout';
import About from './routes/About';
import Contact from './routes/Contact';
// Layout component is the HOC
// we can pass App as parameters
const AppComponent = Layout(App);
// passing About component to Layout hoc as a parameter
const AboutComponent = Layout(About);
// passing Contact component to Layout hoc as a parameter
const ContactComponent = Layout(Contact)
const router = createBrowserRouter(
[
{ path: '/', element: <AppComponent /> },
{ path: '/about', element: <AboutComponent /> },
{ path: '/contact', element: <ContactComponent /> },
],
);
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>,
);
As you can see in the above code, I have used the HOC Layout where the About component is passed to produce a new component called AboutComponent. Therefore you can pass any component to produce a different result.
I hope now you now understand how simple it is to use HOC to build a sidebar nav.
Thank you for reading!
Lead image source.