프론트엔드 공부/React

44일차 프론트엔드 공부 - 이벤트 버블링

프망생222 2025. 1. 1. 16:16

- 프론트엔드 공부 44일차 -


이벤트 버블링

특정 화면 요소에서 이벤트가 발생하였을때, 해당 이벤트가 더 상위의 화면 요소들로 전달되는 특성

 

HTML은 자식요소의 Onclick을 실행하면 부모 요소의 Onclick도 실행되게 된다.

자식요소 -> 부모요소

 

이벤트 캡처링

부모 요소에서 자식 요소의 기능이 실행된다.

import { useQuery, gql } from "@apollo/client";
import { MouseEvent } from "react";

const FETCH_BOARDS = gql`
  query {
    fetchBoards {
      number
      writer
      title
      contents
    }
  }
`;

export default function StaticRoutingMovedPage() {
  const { data } = useQuery(FETCH_BOARDS);
  console.log(data?.fetchBoards);

  const onClickAlert = (event: MouseEvent<HTMLSpanElement>) => {
    alert(event.currentTarget.id + "님이 작성한 글입니다.");
  };
  return (
    <div>
      {data?.fetchBoards.map((el: any) => (
        <div>
          <span>
            <input type="checkbox" />
          </span>
          <span onClick={onClickAlert} id={el.writer}>
            <span style={{ margin: "10px" }}>{el.number}</span>
            <span style={{ margin: "10px" }}>{el.title}</span>
            <span style={{ margin: "10px" }}>{el.writer}</span>
          </span>
        </div>
      ))}
    </div>
  );
}

 

 

게시글 터치 시 작성자의 이름이 있는 토스트 메시지가 생성된다.

 

 const onClickAlert = (event: MouseEvent<HTMLSpanElement>) => {
    alert(event.currentTarget.id + "님이 작성한 글입니다.");
  };

 

event.currentTarget.id : 이벤트가 적용된 요소의 id를 가져오게 된다.

event.target.id를 사용하면 이벤트 버블링 현상으로 인해 부모 요소의 id, 자식 요소의 id와 자신의 id를 번갈아가며 가져오게 되는 현상이 생기게된다.

 

Stoppropagation

상위요소로 해당 이벤트를 전달하지 않고 자신만 이벤트를 감지하도록 한다.

 

import { useQuery, gql } from "@apollo/client";
import { MouseEvent } from "react";
import Checkbox from "./checkbox";

const FETCH_BOARDS = gql`
  query {
    fetchBoards {
      number
      writer
      title
      contents
    }
  }
`;

export default function StaticRoutingMovedPage() {
  const { data } = useQuery(FETCH_BOARDS);
  console.log(data?.fetchBoards);

  const aaa = () => {
    alert("1번 클릭");
  };

  const ddd = (event) => {
    event.stopPropagation();
    alert("4번 클릭");
  };

  return (
    <div>
      {data?.fetchBoards.map((el: any) => (
        <div onClick={aaa}>
          <Checkbox />
          <span onClick={ddd} id={el.writer}>
            <span style={{ margin: "10px" }}>{el.number}</span>
            <span style={{ margin: "10px" }}>{el.title}</span>
            <span style={{ margin: "10px" }}>{el.writer}</span>
          </span>
        </div>
      ))}
    </div>
  );
}

 

export default function Checkbox() {
  const bbb = () => {
    alert("2번 클릭");
  };

  const ccc = (event) => {
    event.stopPropagation();
    alert("3번 클릭");
  };
  return (
    <span onClick={bbb}>
      <input onClick={ccc} type="checkbox" />
    </span>
  );
}
 const ddd = (event) => {
    event.stopPropagation();
    alert("4번 클릭");
  };

 

event.stopPropagation을 사용함으로써  부모, 자식 요소의 이벤트가 실행되지 않고 자신의 이벤트만 실행되도록 한다.

 

주의사항

파일이 분리되어 있더라도 import를 통해 파일이 합쳐진다면 이벤트 버블링 현상이 발생하게 된다.