Sometimes you want to override the browsers default context menu in your react app. You can easily do this with a simple custom react hook. Such custom hook should tell you the X and Y position of the context menu and boolean to say whether you should render the component.

Here is a simple implementation of such custom react hook

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

const useContextMenu = outerRef => {
  const [xPos, setXPos] = useState("0px");
  const [yPos, setYPos] = useState("0px");
  const [menu, showMenu] = useState(false);

  const handleContextMenu = useCallback(
    event => {
      if (outerRef && outerRef.current.contains( {
      } else {
    [showMenu, outerRef, setXPos, setYPos]

  const handleClick = useCallback(() => {
  }, [showMenu]);

  useEffect(() => {
    document.addEventListener("click", handleClick);
    document.addEventListener("contextmenu", handleContextMenu);
    return () => {
      document.removeEventListener("click", handleClick);
      document.removeEventListener("contextmenu", handleContextMenu);
  }, []);

  return { xPos, yPos, menu };

export default useContextMenu;

The hook adds two event listener one to intercept the right click and other to intercept the click event.

  1. When you right click you can get X and Y position of the click using event.pageX and event.pageY
  2. When you left click you toggle the menu so that it gets hidden

Here is a Menu component that uses that hook

import React from "react";

import useContextMenu from "./useContextMenu";

const Menu = ({ outerRef }) => {
  const { xPos, yPos, menu } = useContextMenu(outerRef);

  if (menu) {
    return (
      <ul className="menu" style={{ top: yPos, left: xPos }}>
  return <></>;

export default Menu;

You render the Menu component based on the boolean and you pass the X and Y position as inline styles.

Here is the demo of the custom hook and here is corresponding source code.

This post is also available on DEV.