흔히 웹을 사용하면서 select 태그를 클릭해서 options 들이 나타났을 때, select 태그 내부의 option을 클릭하면 해당 option이 선택되고, option 외부를 클릭했을 때, 나타났던 option들이 사라지도록 구현된 웹을 많이 경험했을 것이다.

나도 그래프를 CustomLegend의 요소를 클릭했을 때, 클릭한 Legend의 Line 그래프를 highlight 시켜주고, CustomLegend 내부의 요소 이외의 영역을 클릭했을 때, 클릭한 요소를 해제하도록 구현해보았다.

1. 선택된 그래프의 x축 값을 상태로 관리한다.

1
const [clickedGraph, setClickedGraph] = useState("");

2. CustomLegend에 이벤트 위임을 해준다.

1
2
3
4
5
6
7
8
9
const CustomLegend = () => {
return (
<ul id="CUSTOM_LEGEND">
{payload.map((elem) => (
<li key={elem.name}>{elem.value}</li>
))}
</ul>
);
};
  • CustomLegend의 ul 태그에 id를 부여한다.
  • li 요소를 클릭 이벤트를 이벤트 위임을 통해 이벤트 발생을 캐치할 수 있다.

3. 이벤트 핸들러 생성

1
2
3
4
5
6
7
8
9
10
11
12
const handleClickGraph = (e: any) => {
const value = e.target.innerHTML;
setClickedGraph(value);
};

const handleClickOutside = (e: any) => {
const parentElem = e.target as HTMLElement;

if (!targetElem.closest("#CUSTOM_LEGEND")) {
setClickedGraph("");
}
};
  • 클릭이벤트가 발생한 요소의 가장 가까운 요소 중 id가 CUSTOM_LEGEND인 요소가 없으면 clickedGraph의 값을 빈 값으로 초기화 시킨다.

4. 브라우저에 이벤트 등록

1
2
3
4
5
6
7
useEffect(() => {
document.addEventListener("click", handleClickOutside);

return () => {
document.removeEventListener("click", handleClickOutside);
};
});
  • 내가 지정한 영역은 ul 태그 안이고 내가 지정하지 않은 외부의 영역을 모두 다루기 위해서는 브라우저에 이벤트를 등록해줘야한다.
  • useEffect는 함수형 컴포넌트에서 리액트 컴포넌트의 라이프사이클에 원하는 함수를 실행할 수 있도록 도와주는 훅이다.
    • return으로 함수를 반환하면 해당 함수는 컴포넌트가 소멸할 때, 실행된다.

렌더링 되기 이전에 브라우저에 이벤트를 등록해주고 해당 컴포넌트가 소멸할 때, 이벤트를 제거해줘야 컴포넌트가 렌더링 될 때마다 이벤트가 중복으로 등록되지 않아 성능상 문제를 해결할 수 있다.

댓글 공유

  • page 1 of 1

loco9939

author.bio


author.job