나의 답안
const onClickAlert = (e: any) => {
alert(`${e.target.id}님이 작성한 글입니다`);
};
return (
<div>
{data?.fetchBoards.map((el: any) => (
<div onClick={onClickAlert} id={el.writer}>
<input type="checkbox"></input>
<span style={{ margin: "10px" }}>{el.number}</span>
<span style={{ margin: "10px" }}>{el.writer}</span>
<span style={{ margin: "10px" }}>{el.title}</span>
</div>
))}
</div>
);
문제 상황
이벤트 버블링 ( 특정 요소에서 이벤트가 발생하면 그 이벤트는 해당 요소에서 시작하여 부모 요소들을 거쳐 최상위 요소 까지 전달 된다 )
이 현상으로 바깥쪽의 div뿐만 아니라 안쪽 span을 누르면 span과 div에 이벤트가 모두 전달된다. 이때 e.target은 가장 안쪽 요소인 span 이 된다.
해결방법
e.currentTarget 을 사용한다
' e.currentTarget ' 은 이벤트 핸들러가 부착된 요소를 가리킨다.
' e.target.value ' 이벤트가 실제로 발생한 요소를 가리킨다.
이벤트 버블링을 막는 방법
이벤트 버블링시 : 3 , 2, 1 차례로 출력
e.stopPropagation() 을 사용한다 : 3번만 출력
const qqq1 = () => {
alert("1번클릭");
};
const qqq2 = () => {
alert("2번클릭");
};
const qqq3 = (e: any) => {
e.stopPropagation();
alert("3번클릭");
};
const qqq4 = () => {
alert("4번클릭");
};
return (
<div>
{data?.fetchBoards.map((el: any) => (
<div id={el.writer} onClick={qqq1}>
<span onClick={qqq2}>
<input type="checkbox" onClick={qqq3}></input>
</span>
<span style={{ margin: "10px" }}>
{el.number} onClick={qqq4}
</span>
<span style={{ margin: "10px" }}>{el.writer}</span>
<span style={{ margin: "10px" }}>{el.title}</span>
</div>
))}
</div>
);
컴포넌트와 이벤트 버블링
컴포넌트에도 이벤트 버블링 현상이 생긴다.
import { useQuery, gql } from "@apollo/client";
import { title } from "process";
import { writer } from "repl";
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 onClickAlert = (e: any) => {
// alert(`${e.currentTarget.id}님이 작성한 글입니다`);
// };
const qqq1 = () => {
alert("1번클릭");
};
const qqq4 = () => {
alert("4번클릭");
};
return (
<div>
{data?.fetchBoards.map((el: any) => (
<div id={el.writer} onClick={qqq1}>
<Checkbox />
<span style={{ margin: "10px" }}>
{el.number} onClick={qqq4}
</span>
<span style={{ margin: "10px" }}>{el.writer}</span>
<span style={{ margin: "10px" }}>{el.title}</span>
</div>
))}
</div>
);
}
export default function Checkbox() {
const qqq2 = () => {
alert("2번클릭");
};
const qqq3 = (e: any) => {
e.stopPropagation();
alert("3번클릭");
};
return (
<span onClick={qqq2}>
<input type="checkbox" onClick={qqq3}></input>
</span>
);
}
728x90
'Frontend 프론트엔드' 카테고리의 다른 글
[ 32 ] ant design 별점 가져와서 사용해보기 (0) | 2024.06.23 |
---|---|
[ 31 ] ant design UI 프레임워크 사용해보기 (0) | 2024.06.23 |
[ 29 ] graphql codegen을 이용해서 Type 다운로드 받고 사용하기 (0) | 2024.06.22 |
[ 28 ] 유틸리티 타입 정리 feat. Record Type (0) | 2024.06.22 |
[ 27 ] 게시판에 타입스크립트 컨테이너/프리젠터 적용 실습 (0) | 2024.06.22 |