Sunday 1 November 2020

ClickAwayListener doesn't fire when clicking on a link/button to navigate to other route

I'm using Material-UI ClickAwayListener component with the existing code that used react-router. The button is outside of the <ClickAwayListener> ... </ClickAwayListener> and so I expected the onClickAway to fire before navigating to other route. But it didn't

Below are the replicate of my code, to some extent to demonstrate what I mean

function Component(){

  const handleClickAway = () => {
    // Do something here
  }

  return (
  <>
    <button>
      <Link to="/other-route">Click here </Link>
    </button>
    // Some other element here
    <ClickAwayListener onClickAway={handleClickAway}>
      <div>
        // Content
      </div>
    </ClickAwayListener>
  </>
  )
}

So if I click any where that is outside of <ClickAwayListener> and <button> the handleClickAway fired, but if I click onto the <button> which contains the like to other route it doesn't.

I tried to look onto source code of ClickAwayListener and this part, I believe, is responsible for detecting the click

 React.useEffect(() => {
    if (mouseEvent !== false) {
      const mappedMouseEvent = mapEventPropToEvent(mouseEvent);
      const doc = ownerDocument(nodeRef.current);

      doc.addEventListener(mappedMouseEvent, handleClickAway);

      return () => {
        doc.removeEventListener(mappedMouseEvent, handleClickAway);
      };
    }

    return undefined;
  }, [handleClickAway, mouseEvent]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>

As far as I can understand, this part will, first add an event listener to click event when the component mount/re-render and will remove that listener before the component unmount (default behavior for useEffect()). But if this is the case, then before the component get unmount by any event that involved clicking outside of the area of ClickAwayListener, the onClickAway listener should be fired because the listener still attach to the click event.

So in short this is the behavior I expect:

Button click --> onClickAway fire --> component get unmount --> go to new route --> clean-up code of useEffect() run --> the listener get removed

But this is what happen so far

Button click --> component get umount --> go to new route --> clean-up code of useEffect() run --> the listener get removed

Can someone help explain to me why this happen?



from ClickAwayListener doesn't fire when clicking on a link/button to navigate to other route

No comments:

Post a Comment