This article has been updated on 2020-05-03

I’m pretty sure that you’ve already seen the effect we are going to make today - It’s a common animation that we see on a lot of websites. When the user scrolls, the navigation bar moves down with a cool animation effect.

You’re lucky today because, in this post, we’ll replicate the same effect with React by building a sticky navbar from scratch with a custom hook.

You can check it live here

Sorry for the interrupt!

If you’re interested in learning React in a comprehensive way, I highly recommend this bestseller course: React - The Complete Guide (incl Hooks, React Router, Redux)

It’s an affiliate link, so by purchasing, you support the blog at the same time.

Setting up the project

To be able to follow along, you need to create a fresh React app by running the following command:

npx create-react-app react-sticky-navbar

Next, structure your folder as follows.

src
├── App.js
├── App.test.js
├── assets
|  └── images
|     └── logo.svg
├── components
|  └── Header
|     ├── About.js
|     ├── Navbar.css
|     ├── Navbar.js
|     ├── Welcome.css
|     └── Welcome.js
├── hooks
|  └── useSticky.js
├── index.css
├── index.js
├── serviceWorker.js
└── setupTests.js

I will focus mostly on the navbar related files to make this post short and useful. You can still find the source code at the end of the article.

Let’s now get hands dirty by writing some code.

  • Header/Welcome.js
import React from "react"

import "./Welcome.css"
import Logo from "../../assets/images/logo.svg"
import About from "./About"

const Welcome = ({ element }) => {
  return (
    <main>
      <section className="welcome">
        <div ref={element}>
          <img src={Logo} alt="logo" className="welcome--logo" />
          <p>Even if you scroll, i will stick with you</p>
          <button className="welcome__cta-primary">Contact us</button>
        </div>
      </section>
      <About />
    </main>
  )
}

export default Welcome

As you can see, here we have a simple component that receives the props element. This last is the reference of the element that will fire the sticky effect later on the scrolling.

By the way, here I use destructuring to pull out the element. If you want too, you can use props.stickyRef.

Now, let’s move on to the next file and create the navigation bar skeleton.

  • Header/Navbar.js
import React from "react"
import "./Navbar.css"
import Logo from "../../assets/images/logo.svg"

const Navbar = () => (
  <nav className="navbar">
    <div className="navbar--logo-holder">
      <img src={Logo} alt="logo" className="navbar--logo" />
      <h1> Stick'Me</h1>
    </div>
    <ul className="navbar--link">
      <li className="navbar--link-item">Home</li>
      <li className="navbar--link-item">About</li>
      <li className="navbar--link-item">Blog</li>
    </ul>
  </nav>
)
export default Navbar

Here, we have for now a very simple component. But later we will update it to be able to display some elements conditionally. And also make the navigation bar sticky.

#react

Build a sticky navigation bar with React
16.75 GEEK