Vadim Semashko
Vadim Semashko

Reputation: 21

onPointerOver and onPointerOut detect all child elements

The problem is that I have onPointerOver and onPointerOut triggered on each child element, but I need it to be on a common group, because then the component is re-rendered too often.

There is a group here, and now when I move the mouse cursor, the component is redrawn many times, I want my state to change only 1 time when I move the mouse cursor and move it away.

This is changing, but the fact is that my head consists of many InstancedMesh, and it turns out that this state changes for each square that my head consists of.

How do I make this work only for the entire group, that is, so that when I hover the cursor, it only reacts to the entire group, and not to individual squares?

Sandbox

    <group
      position={position}
      onPointerOver={(e) => {
        e.stopPropagation();  
        handlePointerOver(e); 
      }}
      onPointerOut={(e) => {
        e.stopPropagation();
        handlePointerOut(e);
      }}
    >
      <Head scale={scale} isVisibleGrid={isVisibleGrid} position={scaledPosition(0, 24, 0)} />

    </group>
  const handlePointerOver = (e: ThreeEvent<PointerEvent>) => {
    setIsVisibleGrid(true);
    e.stopPropagation();
  };

  const handlePointerOut = (e: ThreeEvent<PointerEvent>) => {
    setIsVisibleGrid(false);
    e.stopPropagation();
  };

Upvotes: 2

Views: 117

Answers (1)

WeDoTheBest4You
WeDoTheBest4You

Reputation: 1954

Capture phase events may be useful here

A sample code below shows the same. The code uses click event for demo purpose.

App.js

export default function App() {
  return (
    <>
      <div
        onClickCapture={(e) => {
          console.log('Parent captured');
          e.stopPropagation();
        }}
      >
        Parent
        <br />
        <Child />
      </div>
    </>
  );
}

function Child() {
  return <div onClick={(e) => console.log('Child listened')}>Child</div>;
}

Test run

On load of the App

enter image description here

On clicking on the text Child

Console log generated as below:

// Parent captured

Observation:

Though the click event has been handled in the child component, this handler did not fire when clicking on it. This is due to the capture click event in Parent. It captures the click. Additionally parent stops its propagation too. Since the event propagation has been stopped in Parent, it does not propagate to Child.

Upvotes: 1

Related Questions