Popups, or modals, are a fundamental part of web user interfaces.
They allow you to display important information, gather user input, or highlight specific content without navigating away from the current page.
In this tutorial, we’ll walk you through the process of building a reusable and functional popup component using React.
Prerequisites
Before we begin, make sure you have a basic understanding of React and have Node.js and npm (or yarn) installed on your system.
Step 1: Setting Up Your React Project
If you haven’t already, create a new React project using Create React App
npx create-react-app react-popup-tutorial
cd react-popup-tutorial
Now, open your project in your preferred code editor.
Step 2: Creating the Popup
Component (Popup.js
)
Inside the src
folder of your project, create a new file named Popup.js
. This component will handle the rendering and behavior of our popup.
import React, { useEffect, useRef } from 'react';
import './Popup.css';
const Popup = ({ isOpen, onClose, children }) => {
const popupRef = useRef();
useEffect(() => {
const handleClickOutside = (event) => {
if (popupRef.current && !popupRef.current.contains(event.target)) {
onClose();
}
};
if (isOpen) {
document.addEventListener('mousedown', handleClickOutside);
}
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [isOpen, onClose]);
if (!isOpen) {
return null;
}
return (
<div className="popup-overlay">
<div className="popup-content" ref={popupRef}>
<button className="popup-close-button" onClick={onClose}>
×
</button>
{children}
</div>
</div>
);
};
export default Popup;
Explanation:
- Import Statements: We import
React
,useEffect
, anduseRef
from React, and ourPopup.css
for styling. - Functional Component: We define a functional component
Popup
that accepts three props:isOpen
: A boolean value that determines whether the popup is visible.onClose
: A function to be called when the popup needs to be closed.children
: The content that will be displayed inside the popup.
useRef
: We useuseRef
to create a reference (popupRef
) to the popup content DOM element. This will be used to detect clicks outside the popup.useEffect
: This hook handles the logic for closing the popup when clicking outside of it:- It defines a
handleClickOutside
function that checks if the clicked element (event.target
) is not contained within the popup content (popupRef.current
). If it’s outside, it calls theonClose
function. - An event listener for
mousedown
is added to thedocument
when theisOpen
prop istrue
. - A cleanup function is returned to remove the event listener when the component unmounts or when
isOpen
becomesfalse
, preventing memory leaks.
- It defines a
- Conditional Rendering: If
isOpen
isfalse
, the component returnsnull
, and nothing is rendered. - JSX Structure:
.popup-overlay
: Adiv
that covers the entire viewport with a semi-transparent background..popup-content
: Adiv
that holds the actual popup content. Theref
attribute is attached to this element..popup-close-button
: A button with an “×” symbol that calls theonClose
function when clicked.{children}
: This renders any content that is passed between the<Popup>
tags in the parent component.
Step 3: Styling the Popup (Popup.css
)
Create a new file named Popup.css
in the src
folder and add the following styles:
.popup-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.popup-content {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
position: relative;
max-width: 500px;
width: 90%;
}
.popup-close-button {
position: absolute;
top: 10px;
right: 10px;
background: none;
border: none;
font-size: 20px;
cursor: pointer;
}
Explanation:
.popup-overlay
: This style makes the overlay fixed to cover the entire screen, provides a semi-transparent background to dim the underlying content, uses Flexbox to center the popup content, and sets a highz-index
to ensure it appears on top of other elements..popup-content
: Styles the main popup container with a white background, padding, rounded corners, a subtle box shadow, and sets itsposition
torelative
so that the close button can be positioned absolutely within it..popup-close-button
: Styles the close button, positioning it absolutely in the top-right corner of the popup content.
Step 4: Using the Popup
Component (App.js
)
Now, let’s integrate the Popup
component into our main application. Open src/App.js
and modify it as follows:
import React, { useState } from 'react';
import Popup from './Popup';
import './App.css';
function App() {
const [isPopupOpen, setIsPopupOpen] = useState(false);
const openPopup = () => {
setIsPopupOpen(true);
};
const closePopup = () => {
setIsPopupOpen(false);
};
return (
<div className="App">
<h1>My React App</h1>
<button onClick={openPopup}>Open Popup</button>
<Popup isOpen={isPopupOpen} onClose={closePopup}>
<h2>Popup Content</h2>
<p>This is the content of the popup.</p>
<button onClick={closePopup}>Close</button>
</Popup>
</div>
);
}
export default App;
Explanation:
- We import the
Popup
component and theApp.css
file. - We use the
useState
hook to manage the visibility of the popup with theisPopupOpen
state variable, initially set tofalse
. openPopup
andclosePopup
functions are defined to update theisPopupOpen
state.- In the
return
statement:- A button is rendered that, when clicked, calls
openPopup
to show the popup. - The
Popup
component is rendered conditionally based on theisPopupOpen
state. - We pass the
isPopupOpen
state as theisOpen
prop and theclosePopup
function as theonClose
prop to thePopup
component. - The content you want to display inside the popup (an
h2
, ap
, and another button in this case) is passed aschildren
to thePopup
component. The “Close” button inside the popup also calls theclosePopup
function.
- A button is rendered that, when clicked, calls
Step 5: Basic App Styling (App.css
)
You can add some minimal styling to src/App.css
to center the content and style the button:
.App {
font-family: sans-serif;
text-align: center;
padding: 20px;
}
button {
padding: 10px 15px;
font-size: 16px;
cursor: pointer;
}
Step 6: Running Your Application
Save all your files and start your React development server:
npm start
Navigate to http://localhost:3000
in your browser. You should see a button labeled “Open Popup”.
Clicking this button will display the popup with the content you provided, and you can close it by clicking the “×” button or by clicking anywhere outside the popup content area.
Conclusion
In this tutorial, you’ve learned how to create a basic yet functional and reusable popup component in React.
This component can be easily integrated into your projects and customized with different content and styling as needed.
The use of useState
to control visibility and useRef
along with a useEffect
hook to handle outside clicks are common and effective patterns in React development.
Feel free to expand upon this foundation to create more complex and interactive modal experiences in your applications.