How to Manage Scroll Lock for Nested Popups in React Using a Custom Hook and Tailwind CSS

Tamjid Mostafa

Tamjid Mostafa

ยท 5 min read
Manage Scroll Lock

To ensure the code and text are properly indented and formatted for readability, I'll reformat the entire content, including the code snippets. This will help ensure that the document looks clean and the code is easy to read and follow.

Managing Scroll Lock for Nested Popups in React Using a Custom Hook and Tailwind CSS

When dealing with popups in web applications, especially nested popups, managing the scroll state of the background content becomes crucial to ensure a smooth user experience. In this article, we will create a custom React hook to manage scroll locking and use it in a nested popup example. We'll also use Tailwind CSS for styling.

Table of Contents

  1. Introduction
  2. Creating the Custom Scroll Lock Hook
  3. Building the Example Component
  4. Styling with Tailwind CSS
  5. Conclusion

Introduction

Managing the scroll state is essential when popups appear on a webpage to prevent the background content from scrolling. This becomes even more critical when dealing with nested popups, where multiple layers of popups might require independent scroll locks. We'll implement a custom hook useScrollLock to handle this and demonstrate its use in a React component.

Creating the Custom Scroll Lock Hook

The useScrollLock hook will manage a scroll lock count to ensure that the scroll state is only unlocked when all popups are closed.

import { useState, useEffect } from "react";

const useScrollLock = () => {
const [lockCount, setLockCount] = useState(0);

useEffect(() => {
if (lockCount > 0) {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "auto";
}
}, [lockCount]);

const lockScroll = () => setLockCount((count) => count + 1);
const unlockScroll = () => setLockCount((count) => Math.max(count - 1, 0));

return { lockScroll, unlockScroll };
};

export default useScrollLock;

Building the Example Component

Next, we will create an example component that uses the useScrollLock hook. This component will have a main popup and a nested popup. The background scroll will be locked when either popup is open, and it will be unlocked only when both popups are closed.

import React, { useState, useEffect } from "react";
import useScrollLock from "./useScrollLock";

const NestedPopupExample = () => {
const { lockScroll, unlockScroll } = useScrollLock();
const [isMainPopupOpen, setIsMainPopupOpen] = useState(false);
const [isNestedPopupOpen, setIsNestedPopupOpen] = useState(false);

useEffect(() => {
if (isMainPopupOpen) {
lockScroll();
} else {
unlockScroll();
}
}, [isMainPopupOpen]);

useEffect(() => {
if (isNestedPopupOpen) {
lockScroll();
} else {
unlockScroll();
}
}, [isNestedPopupOpen]);

return (
<div className="flex flex-col items-center justify-center min-h-screen"> <button className="px-4 py-2 bg-blue-500 text-white rounded" onClick={() => setIsMainPopupOpen(true)} > Open Main Popup </button> {isMainPopupOpen && ( <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50"> <div className="bg-white p-6 rounded shadow-lg"> <h2 className="text-xl font-bold mb-4">Main Popup</h2> <button className="px-4 py-2 bg-red-500 text-white rounded mr-2" onClick={() => setIsMainPopupOpen(false)} > Close Main Popup </button> <button className="px-4 py-2 bg-green-500 text-white rounded" onClick={() => setIsNestedPopupOpen(true)} > Open Nested Popup </button> {isNestedPopupOpen && ( <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50"> <div className="bg-white p-6 rounded shadow-lg"> <h3 className="text-lg font-bold mb-4">Nested Popup</h3> <button className="px-4 py-2 bg-red-500 text-white rounded" onClick={() => setIsNestedPopupOpen(false)} > Close Nested Popup </button> </div> </div> )} </div> </div> )} </div>
);
};

export default NestedPopupExample;

Conclusion

In this article, we demonstrated how to create a custom scroll lock hook in React and use it to manage scroll locking for nested popups. We also used Tailwind CSS to style our components, ensuring a clean and modern design. This approach ensures a smooth user experience by preventing background scrolling when popups are open, even with multiple nested popups.

This detailed guide should now properly format and indent the code and text for readability, ensuring that it's easy to follow and understand.

Tamjid Mostafa

About Tamjid Mostafa

#coding, #youtube, #webdevelopment, #contentcreation, and #fullstackwebdeveloper, weaving together my diverse interests. I'm currently embarking on an exciting journey at Mediaslide as a Fron End Developer. ๐Ÿ’ป๐ŸŒŸ