88 */
99
1010import * as React from 'react' ;
11- import { useLayoutEffect , createRef } from 'react' ;
11+ import { useLayoutEffect } from 'react' ;
1212import { createPortal } from 'react-dom' ;
1313
1414import ContextMenuItem from './ContextMenuItem' ;
1515
1616import type {
1717 ContextMenuItem as ContextMenuItemType ,
1818 ContextMenuPosition ,
19- ContextMenuRef ,
2019} from './types' ;
2120
2221import styles from './ContextMenu.css' ;
@@ -49,15 +48,13 @@ type Props = {
4948 items : ContextMenuItemType [ ] ,
5049 position : ContextMenuPosition ,
5150 hide : ( ) => void ,
52- ref ? : ContextMenuRef ,
5351} ;
5452
5553export default function ContextMenu ( {
5654 anchorElementRef,
5755 position,
5856 items,
5957 hide,
60- ref = createRef ( ) ,
6158} : Props ) : React . Node {
6259 // This works on the assumption that ContextMenu component is only rendered when it should be shown
6360 const anchor = anchorElementRef . current ;
@@ -73,14 +70,21 @@ export default function ContextMenu({
7370 '[data-react-devtools-portal-root]' ,
7471 ) ;
7572
76- useLayoutEffect ( ( ) => {
77- const menu = ref . current ;
73+ const hideMenu = portalContainer == null || items . length === 0 ;
74+ const menuRef = React . useRef < HTMLDivElement | null > ( null ) ;
7875
79- // Match the early-return condition below. If neither of these
80- // is true, menu being null would be a bug .
81- if ( portalContainer == null || items . length === 0 ) {
76+ useLayoutEffect ( ( ) => {
77+ // Match the early-return condition below .
78+ if ( hideMenu ) {
8279 return ;
8380 }
81+ const maybeMenu = menuRef . current ;
82+ if ( maybeMenu === null ) {
83+ throw new Error (
84+ "Can't access context menu element. This is a bug in React DevTools." ,
85+ ) ;
86+ }
87+ const menu = ( maybeMenu : HTMLDivElement ) ;
8488
8589 function hideUnlessContains ( event : Event ) {
8690 if ( ! menu . contains ( ( ( event . target : any ) : Node ) ) ) {
@@ -104,14 +108,14 @@ export default function ContextMenu({
104108
105109 ownerWindow . removeEventListener ( 'resize' , hide ) ;
106110 } ;
107- } , [ ] ) ;
111+ } , [ hideMenu ] ) ;
108112
109- if ( portalContainer == null || items . length === 0 ) {
113+ if ( hideMenu ) {
110114 return null ;
111115 }
112116
113117 return createPortal (
114- < div className = { styles . ContextMenu } ref = { ref } >
118+ < div className = { styles . ContextMenu } ref = { menuRef } >
115119 { items . map ( ( { onClick, content} , index ) => (
116120 < ContextMenuItem key = { index } onClick = { onClick } hide = { hide } >
117121 { content }
0 commit comments