When building web applications, sometimes you might need to provide a customized right-click context menu to enhance the user experience. In this article, I'm going to explore how to create a custom right-click menu in a React application.
Before starting, it's worth mentioning that there are some existing libraries available that offer solutions for context menu (like react-contextmenu or react-contexify or react-context-menu). If you don't want to use the library and want to roll up your sleeves to create a customized solution tailored to your application's unique needs, let's move on!
A context menu, often referred to as a right-click menu, is a pop-up menu that appears when a user right-clicks on an element.
the oncontextmenu
event is typically triggered by clicking the right mouse button. In the context of React, we can utilize the onContextMenu
event to capture the right-click action.
For further details, you can refer to the MDN Web Docs or w3schools Doc
To prevent the default context menu from showing up, we can use the preventDefault()
method on the event object:
function Home() {
const handleContextMenu = (e) => {
e.preventDefault(); // prevent the default behavior when right-clicked
console.log("right click");
};
return (
<div onContextMenu={handleContextMenu}>
{/* Your content here */}
</div>
);
}
export default Home;
First, let's create a new component called CustomMenu
. This component will render the menu items and handle the actions when a menu item is clicked.
This component takes two props: handleMenuItemClick
for handling menu item clicks and menuPosition
for positioning the menu based on the mouse coordinates.
import React from 'react';
function CustomMenu({ handleMenuItemClick, menuPosition }) {
const menuItems = ['foo', 'bar', 'item3'];
const handleClick = (item) => {
handleMenuItemClick(item);
};
return (
<div className="custom-menu rounded shadow bg-white absolute" style={{ left: menuPosition.x, top: menuPosition.y }}>
{menuItems.map((item) => (
<div className="cursor-pointer rounded px-4 py-2 hover:bg-slate-400" key={item} onClick={() => handleClick(item)}>
{item}
</div>
))}
</div>
);
}
export default CustomMenu;
Now, let's integrate the custom context menu into our main component.
When the user right-clicks, we'll set the menuVisible
state to true
and also store the mouse coordinates to determine the menu position.
import React, { useState } from 'react';
import CustomMenu from './CustomMenu';
function Home() {
const [menuVisible, setMenuVisible] = useState(false);
const [menuPosition, setMenuPosition] = useState({ x: 0, y: 0 });
const handleContextMenu = (e) => {
e.preventDefault();
setMenuVisible(true);
// Store the mouse coordinates
const mouseX = e.clientX;
const mouseY = e.clientY;
setMenuPosition({ x: mouseX, y: mouseY });
// Add an event listener to handle clicks outside the menu
document.addEventListener('click', handleOutsideClick);
};
const handleOutsideClick = (e) => {
// Check if the click is outside the menu
if (!e.target.closest('.custom-menu')) {
setMenuVisible(false);
document.removeEventListener('click', handleOutsideClick);
}
};
const handleMenuItemClick = (item) => {
switch (item) {
case 'foo':
// Perform the foo action
break;
case 'bar':
// Perform the bar action
break;
default:
break;
}
setMenuVisible(false);
};
return (
<div onContextMenu={handleContextMenu}>
{/* Your other content here */}
{menuVisible && <CustomMenu handleMenuItemClick={handleMenuItemClick} menuPosition={menuPosition} />}
</div>
);
}
export default Home;
Now, let's take a look at the result:
Feel free to customize the design and behavior of the custom menu to fit your application's style and requirements.
With this approach, you can create context menus that provide specific actions and options, making your application more user-friendly and efficient.
Scan the QR Code to add me on WeChat