Building A Navigation That Changes Dynamically on Scroll Using React Hooks

Chigozie Orunta
4 min readApr 24, 2020

When I started building websites with React, I also wondered how I was going to build a navigation that changed dynamically on a user scroll activity.

It turns out that it was a lot easier than I thought. Let’s take a look at how to achieve this.

  1. Create Navigation Component

I’ll assume you have the necessary React app setup. In your source folder (src), create a file, and call it Navigation.js. To create our react-navigation, we’ll use a functional component like so:

import React from "react";const Navigation = () => {
return (
<ul>
<li><a href="https://yoursite.com">Home</a></li>
<li><a href="https://yoursite.com/articles">Articles</a></li>
<li><a href="https://yoursite.com/gallery">Gallery</a></li>
<li><a href="https://yoursite.com/contact">Contact</a></li>
</ul>
);
}
export default Navigation;

The above Navigation component simply returns an unordered list with links to various sections of your site.

2. Add Navigation Styling

Next, we will create the styling for the navigation component. There are several ways of doing this, however, we will use the inline style approach to enable us to manipulate the styling for our navigation when the user scrolls.

We will create two objects containing the styling properties we want to dynamically change:

const navTop = {
backgroundColor: "#333",
transition: "all 0.3s",
};
const navScroll = {
backgroundColor: "#F00",
transition: "all 0.3s",
};

Adding this to our component, we have:

import React from "react";const navTop = {
backgroundColor: "#333",
transition: "all 0.3s",
};
const navScroll = {
backgroundColor: "#F00",
transition: "all 0.3s",
};
const Navigation = () => {
return (
<ul style={navTop}>
<li><a href="https://yoursite.com">Home</a></li>
<li><a href="https://yoursite.com/articles">Articles</a></li>
<li><a href="https://yoursite.com/gallery">Gallery</a></li>
<li><a href="https://yoursite.com/contact">Contact</a></li>
</ul>
);
}
export default Navigation;

You can also add a default styling for the above component in a separate CSS file (Navigation.css) on your source folder and add to the Navigation component like so:

import React from "react";
import "./Navigation.css"
const navTop = {
backgroundColor: "#333",
transition: "all 0.3s",
};
const navScroll = {
backgroundColor: "#F00",
transition: "all 0.3s",
};
const Navigation = () => {
return (
<ul className="nav" style={navTop}>
<li><a href="https://yoursite.com">Home</a></li>
<li><a href="https://yoursite.com/articles">Articles</a></li>
<li><a href="https://yoursite.com/gallery">Gallery</a></li>
<li><a href="https://yoursite.com/contact">Contact</a></li>
</ul>
);
}
export default Navigation;

3. Implement React Hooks!

This is where the magic happens, we introduce React hooks. If you don’t know about React hooks, you might want to learn more about them. They come in very handy for helping us create functional components with states.

Before now, this was only possible with class components, but now we can achieve state management with functional components using React Hooks! The hooks will help us change the state of the component when the user scrolls.

For our component, we will use 2 React hooks namely: useState & useEffect hooks.

import React, { useState, useEffect } from "react";

The useState react hook helps us set the initial state (navState) of the Navigation component to our navTop object and helps us specify the setter method (setNavState) which changes the navState when the user scrolls.

const [navState, setNavState] = useState(navTop);

We would also specify that the style for our Navigation component should be the navState like so:

<ul className="nav" style={navState}>

Adding the above lines of code to our component and we have:

import React, { useState, useEffect } from "react";
import "./Navigation.css"
const navTop = {
backgroundColor: "#333",
transition: "all 0.3s",
};
const navScroll = {
backgroundColor: "#F00",
transition: "all 0.3s",
};
const Navigation = () => {
const [navState, setNavState] = useState(navTop);
return (
<ul className="nav" style={navState}>
<li><a href="https://yoursite.com">Home</a></li>
<li><a href="https://yoursite.com/articles">Articles</a></li>
<li><a href="https://yoursite.com/gallery">Gallery</a></li>
<li><a href="https://yoursite.com/contact">Contact</a></li>
</ul>
);
}
export default Navigation;

And finally, we use the useEffect hook to capture the onscroll event of the window. This allows us to destructure the window object’s properties and test for when the user scrolls to a particular point (in this case, 100px before the bottom of the screen):

useEffect(() => {
window.onscroll = () => {
const { innerHeight: height, scrollY: scrollPosition } = window;
scrollPosition > height - 100
? setNavState(navScroll)
: setNavState(navTop);
};
}, []);

Adding this to our component we have this:

import React, { useState, useEffect } from "react";
import "./Navigation.css"
const navTop = {
backgroundColor: "#333",
transition: "all 0.3s",
};
const navScroll = {
backgroundColor: "#F00",
transition: "all 0.3s",
};
const Navigation = () => {
const [navState, setNavState] = useState(navTop);
useEffect(() => {
window.onscroll = () => {
const { innerHeight: height, scrollY: scrollPosition } = window;
scrollPosition > height - 100
? setNavState(navScroll)
: setNavState(navTop);
};
}, []);
return (
<ul className="nav" style={navState}>
<li><a href="https://yoursite.com">Home</a></li>
<li><a href="https://yoursite.com/articles">Articles</a></li>
<li><a href="https://yoursite.com/gallery">Gallery</a></li>
<li><a href="https://yoursite.com/contact">Contact</a></li>
</ul>
);
}
export default Navigation;

Conclusion

And finally, we have a complete Navigation component that responds dynamically to the user’s scrolling activity using React Hooks. You can see an example of this on a pet project of mine at CodeHub.pro.

Now you too can create something cool of your choice.

Happy coding…

--

--