Unlock the Power of Custom Context Menus in React

What is a Context Menu?

A context menu, also known as a right-click menu, is a graphical user interface (GUI) menu that appears when a user interacts with an application or operating system. It provides a limited set of choices relevant to the current state or context.

Getting Started with Our React Project

To create a custom right-click menu in React, let’s initialize a new React project using npx create-react-app react-context-menu and set up our project structure. We’ll use styled-components for styling and create four folders: components, data, hooks, and styles.

npx create-react-app react-context-menu

Disabling the Default Right-Click Context Menu

By default, browsers display their native context menu when you right-click. To disable this behavior, we’ll use the onContextMenu prop in our App.js file. This will prevent the default menu from appearing when we right-click on our custom context menu.

import React from 'eact';

function App() {
  return (
    
e.preventDefault()} />
);
}

export default App;

Creating a Custom Right-Click Context Menu

To create a custom context menu, we’ll create a data.js file to store our data and a MenuContext.js component to render our menu items. We’ll then use the onContextMenu prop to prevent the default browser behavior and display our custom menu.

// data.js
export const menuItems = [
  { id: 1, label: 'Save' },
  { id: 2, label: 'Print' },
  { id: 3, label: 'Create QR Code' },
];
// MenuContext.js
import React from 'eact';
import { menuItems } from '../data';

function MenuContext() {
  return (
    {menuItems.map((item) => (

  • {item.label}
  • ))}


  );
}

export default MenuContext;

Implementing the Custom Right-Click Menu

Next, we’ll implement our custom right-click menu by mapping over our data array and rendering our menu items. We’ll use the useEffect Hook to register an event listener and clean up the event to avoid memory leaks.

import React, { useState, useEffect } from 'eact';
import MenuContext from './MenuContext';

function App() {
  const [clicked, setClicked] = useState(false);
  const [points, setPoints] = useState({ x: 0, y: 0 });

  useEffect(() => {
    document.addEventListener('click', (e) => {
      if (!e.target.classList.contains('menu-item')) {
        setClicked(false);
      }
    });
    return () => {
      document.removeEventListener('click', () => {});
    };
  }, []);

  const handleContextMenu = (e) => {
    e.preventDefault();
    setClicked(true);
    setPoints({ x: e.clientX, y: e.clientY });
  };

  return (
{clicked && (

)}


  );
}

export default App;

Displaying the Right-Click Context Menu

When we right-click on our menu items, we’ll display the custom context menu at the correct position using the x and y coordinates of the mouse click. We’ll also ensure that the menu disappears when we click anywhere else on the page.

Styling the Context Menu

To style our context menu, we’ll create a ContextMenu div that’s only displayed when the clicked state is true. We’ll pass the x and y coordinates as props to style the menu’s position.

.ContextMenu {
  position: absolute;
  background-color: #fff;
  border: 1px solid #ddd;
  padding: 10px;
  display: none;
}

.ContextMenu.show {
  display: block;
}

Creating a Custom Context Menu Hook

To create a reusable custom context menu Hook, we’ll create a useContextMenu.js file that declares two states: clicked and points. We’ll then use the useEffect Hook to register an event listener and clean up the event.

// useContextMenu.js
import { useState, useEffect } from 'eact';

function useContextMenu() {
  const [clicked, setClicked] = useState(false);
  const [points, setPoints] = useState({ x: 0, y: 0 });

  useEffect(() => {
    document.addEventListener('click', (e) => {
      if (!e.target.classList.contains('menu-item')) {
        setClicked(false);
      }
    });
    return () => {
      document.removeEventListener('click', () => {});
    };
  }, []);

  const handleContextMenu = (e) => {
    e.preventDefault();
    setClicked(true);
    setPoints({ x: e.clientX, y: e.clientY });
  };

  return { clicked, points, handleContextMenu };
}

export default useContextMenu;
  • When creating your own custom context menu, consider mobile interaction and ensure that your menu doesn’t cause bad user experiences.

Leave a Reply