[ React ] 하위 요소가 클릭 되는 것을 막아주는 e.currentTarget.click()

방충림·2023년 5월 19일
4

Catch the error

목록 보기
7/7
post-thumbnail

현상

다음과 같은 대시보드 페이지를 구성 했다.

각각의 차트를 클릭하면 차트의 Detail 페이지로 이동하고자 했다.
예를 들어 /allCharts/amountAndPrice 라는 경로로 이동해야했다.

하지만 예상치 못한 오류가 발생했다.
간헐적으로 /allCharts/amountAndPrice가 아닌 /allCharts 경로로 이동을 하는 것이었다.

원인

왜 이런 현상이 일어나는지 클릭 이벤트를 들여다보았다.

 const enter = (e) => {
    console.log(e);
}

문제를 깨달았다. 그래프를 눌렀을 때 div의 하위 요소들이 클릭되었고, 그 요소들은 id값을 가지고 있지 않으므로 undefined를 반환하였다.

따라서 navigate("/allCharts/undefined") 가 실행되면서 /allCharts/으로 이동했던 것이다.

해결방안

어떻게하면 이것을 수정할 수 있을까?

e.currentTarget.click()e.target.tagName을 활용해서 해결할 수 있다.

e.currentTarget.click()은 JavaScript에서 이벤트를 강제로 발생시키는 메서드입니다. 일반적으로 이벤트는 특정 요소에서 발생하며, 해당 요소에 이벤트 핸들러가 연결되어 있어야 합니다. 그러나 때로는 특정 요소의 이벤트를 다른 요소에서 강제로 발생시켜야 할 때가 있습니다.
.
e.currentTarget는 이벤트가 연결된 핸들러가 실행되는 동안 이벤트를 처리하는 현재 요소를 가리킵니다. 따라서 e.currentTarget.click()은 현재 요소에 대해 클릭 이벤트를 강제로 발생시킵니다. 이를 통해 다른 요소에서 이벤트를 트리거하거나 이벤트를 전파시킬 수 있습니다.

수정된 코드를 먼저 보고 설명을 이어가겠다.

해당 부분의 코드는 다음과 같다.

수정 전 코드

export default function Dashboard()
.
.
  const navigate = useNavigate();
    navigate(`/allCharts/${e.target.id}`, {
      state: {
        data: chartsData.filter((item) => item.id === e.target.id)[0],
      },
    });
.
.

return
.
.
.
      <div
        id='amountAndPrice'
        onClick={enter}
        to='/allCharts/amountAndPrice'
        className={`${styles.box} ${styles.box6}`}
      >
        <AmountAndPrice />
      </div>
.
.
.

( 태그로도 할 수 있지만 사정이 있어 useNavigate만 가능했음)

수정 후 코드

export default function Dashboard()
.
.
  const navigate = useNavigate();

  const enter = (e) => {
    if (e.target.tagName.toLowerCase() !== "div") {
      e.currentTarget.click(); // 상위 <div> 요소 클릭 이벤트 강제 실행
      return;
    }

    navigate(`/allCharts/${e.target.id}`, {
      state: {
        data: chartsData.filter((item) => item.id === e.target.id)[0],
      },
    });
.
.

return
.
.
.
      <div
        id='amountAndPrice'
        onClick={enter}
        to='/allCharts/amountAndPrice'
        className={`${styles.box} ${styles.box6}`}
      >
        <AmountAndPrice />
      </div>
.
.
.

그래프의 이곳 저곳을 눌러보았다. e.target.tagName 에는 'path', svg 등 누르는 곳에 따라 다양한 값이 출력되었다.

위의 코드에서 e.currentTarget.click()은 <div> 요소가 아닌 하위요소를 클릭했을 때 상위 <div> 요소의 클릭 이벤트를 강제로 발생시키는 역할을 한다. 이렇게 함으로써 <Pir>을 클릭해도 실제로는 상위 <div>의 클릭 이벤트가 발생하게 된다.

이로써 어느 곳을 눌러도 정상적으로 원하는 경로로 navigate 되게된다.

다만, 주의할 점 한가지, 하위요소들에 div가 있다면, if문 조건을 조금 더 디테일하게 수정해야 할 것이다.

추가 내용

+ 추가적으로 상위 요소의 클릭이벤트 때문에 하위요소의 클릭이벤트가 작동하지 않는 경우도 있다. 이 경오에는 e.stopPropagation(); 를 사용해서 상위 요소로부터 내려오는 이벤트 상속을 끊어줄 수 있다. 자세한 내용은 추후 다시 포스팅하겠다.

profile
최선이 반복되면 최고가 된다.

0개의 댓글