3

I have onContextMenu events attached to a parent and child components. Both are react synthetic events, yet event.stopPropagation fails to stop this.

BOTH ARE REACT EVENTS

Edit: I had an epiphany,is it because im hydrating inside a content-editable div? and react doesnt know that both components are child and parent as react ignores content inside editable divs. is there a way to make react understand this?

ParentComponent

 const CMSCheckBox = (props, ref) => {
      openMenu=()=>{
        alert("Parent");
    }
   //hydrating components based on props
    useEffect(() => {
    if (props.objValue && props.objValue.SubElements) {
       props.objValue.SubElements.map(SubElement => {
           let strDivId = SubElement.DivId ? SubElement.DivId : "element_" + SubElement.iElementId;
           if (!document.getElementById(strDivId)) {
               let objSavedSel = ApplicationState.GetProperty("objActiveSelection");
               if (objSavedSel && objSavedSel != null) {
                   let divElement;
                   divElement = document.createElement("span");
                   ApplicationState.SetProperty("objActiveDiv",
                    {
                       strDivId: strDivId
                   });
                   divElement.id = strDivId;
                   divElement.setAttribute('type', SubElement.iElementType.toLowerCase() + 'div');
                   let range = document.createRange();
                   range.setStart(document.getElementById(objSavedSel.divId),
              0);
                   range.collapse(true);
                   var nodeStack = [document.getElementById(objSavedSel.divId)
              ], node, foundStart = false, stop = false, charIndex = 0;
                   while (!stop && (node = nodeStack.pop())) {
                       if (node.nodeType == 3) {
                           var nextCharIndex = charIndex + node.length;
                           if (!foundStart && objSavedSel.intStart >= charIndex && objSavedSel.intStart <= nextCharIndex) {
                               range.setStart(node, objSavedSel.intStart - charIndex);
                               foundStart = true;
                  }
                           if (foundStart && objSavedSel.intEnd >= charIndex && objSavedSel.intEnd <= nextCharIndex) {
                               range.setEnd(node, objSavedSel.intEnd - charIndex);
                               stop = true;
                  }
                           charIndex = nextCharIndex;
                } else {
                           var i = node.childNodes.length;
                           while (i--) {
                               nodeStack.push(node.childNodes[i
                    ]);
                  }
                }
              }
                   range.deleteContents();

                   range.insertNode(divElement); //insert div to hydrate
            }
          }

           let Element = UndoRedo(ElementController.getComponent(SubElement.iElementType.toLowerCase()));
           ReactDom.hydrate(<Provider store={store
          } ><Element ElementJson={SubElement
          } PageId={props.PageId
          } Mode={props.Mode
          } /></Provider>, document.getElementById(strDivId));
           // setTimeout(() => {
          //     onContentChange();
          // }, 100);
        })
      }
    return () => {
       divRef.current.removeEventListener("blur", onContentChange_Callbck);
       divRef.current.removeEventListener("mousedown", onMouseDown_Callbck);
      }
    },
    [state, props
    ])
     retrun (<div onContextMenu={} contenteditable="true"></div>)
    }

Child components are hydrated into the content-editable div in the parent component based on click position

const Child =(props,ref) =>{
  const openmenu=(e)=>{
   e.stopPropagation(); //doesnt work
    alert("child");
  }
 return (<div onContextMenu={openmenu}>Test</div>);
}

both context menu events gets called

Sujit.Warrier
  • 2,815
  • 2
  • 28
  • 47
  • Possible duplicate of [ReactJS SyntheticEvent stopPropagation() only works with React events?](https://stackoverflow.com/questions/24415631/reactjs-syntheticevent-stoppropagation-only-works-with-react-events) – helloitsjoe May 02 '19 at 02:44
  • as explained both are react events so above doesnt apply – Sujit.Warrier May 02 '19 at 02:44

2 Answers2

2
e.nativeEvent.stopImmediatePropagation();

this reference guide documents the SyntheticEvent

SIMDD
  • 615
  • 5
  • 15
1

So the problem is as stated in my edit, since my div is content editable, react doesnt know that that both are parent and child dom elements and hence does nothing when stopPropagation is called.

The solution I found albeit a messy one was to add the child component as ref then attach the react event handler using the addEventListener method of javascript. since the event is not synthetic anymore and not managed by react, the event no longer bubbles up to the parent.

Sujit.Warrier
  • 2,815
  • 2
  • 28
  • 47