Building a Sidebar in React with a Higher-Order Component

Written by Habibu | Published 2023/01/31
Tech Story Tags: react | higher-order-components | react-router-v6 | web-development | javascript | javascript-frameworks | reactjs | software-development

TLDRA higher-order component takes another component as a parameter and returns a new modified component. When you have a component which has constant elements and you want to display the variable components inside of it the simple way is to use Higher order component (HOC) To make this concept into a real-world example, I’m going to build a sidebar nav.via the TL;DR App

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.


Written by Habibu | Full-stack software developer. Ruby | Ruby on Rails | Javascript | React | Redux | React-native | Typescript
Published by HackerNoon on 2023/01/31