다음과 같은 대시보드 페이지를 구성 했다.
각각의 차트를 클릭하면 차트의 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(); 를 사용해서 상위 요소로부터 내려오는 이벤트 상속을 끊어줄 수 있다. 자세한 내용은 추후 다시 포스팅하겠다.