
리액트: 모바일(iPhone)에서 onClick 이벤트 동작 시 2번 탭이 필요한가요?
리액트로 작업하다가 모바일(iPhone)에서 클릭 가능한 컴포넌트의 onClick 이벤트가 한 번이 아니라 두 번 탭해야만 동작하는 현상을 경험한 적이 있나요? 이 블로그 포스트에서는 이 문제를 탐구하고 해결할 수 있는 잠재적인 해결책을 제공할 것입니다.
문제점
리액트로 클릭 가능한 컴포넌트가 포함된 프로젝트를 작업 중이라면, 모바일(iPhone)에서 버튼을 탭해도 onClick 이벤트가 두 번 탭한 후에만 트리거되는 상황에 마주친 적이 있을 겁니다. 이러한 동작은 사용자에게 답답한 경험을 제공하므로 해결해야 할 문제입니다.
조사를 진행해보면, 이 문제는 안드로이드 태블릿에서는 발생하지 않지만 iPhone에서 특정한 현상임을 알 수 있습니다. 게다가, 호버 효과를 위해 onMouseEnter 및 onMouseLeave 이벤트를 구현한 경우에는 이러한 이벤트가 onClick 이벤트와 간섭할 수 있습니다.
잠재적인 해결책
iPhone에서 두 번 탭하는 문제를 해결하기 위해 몇 가지 잠재적인 해결책을 살펴보겠습니다:
1. onMouseEnter 및 onMouseLeave 대신 onMouseOver 및 onMouseOut 사용
한 가지 가능한 해결책은 non-bubbling 이벤트인 onMouseEnter 및 onMouseLeave을 onMouseOver 및 onMouseOut으로 대체하는 것입니다. 이벤트 버블링 솔루션을 사용하여 두 번 탭하는 문제를 해결할 수 있을지도 모릅니다.
const CardSource = ({ addCard, note, setHoveredNote, hoveredNote }) => {
return (
<Source
onClick={() => addCard(note)}
onMouseOver={() => setHoveredNote(note)}
onMouseOut={() => setHoveredNote(null)}
className={
hoveredNote && hoveredNote.index === note.index ? "highlight" : null
}
>
{note.letters[0]}
</Source>
);
};
2. 이벤트 타입 디버깅
위의 해결책이 작동하지 않는 경우, 이벤트 타입을 사용하여 문제를 디버깅해 볼 수 있습니다. 마우스오버, 마우스아웃, 클릭 등의 이벤트에 대해 이벤트 종류를 기반으로 처리해보세요. 이 접근 방식을 사용하면 사용자 정의 이벤트 처리를 구현하고 이벤트 유형 사이의 잠재적인 충돌을 해결할 수 있습니다.
const CardSource = ({ addCard, note, setHoveredNote, hoveredNote }) => {
const eventHandler = (event) => {
const { type, bubbles } = event;
switch(type) {
case "mouseover":
case "mouseenter":
setHoveredNote(note);
break;
case "mouseout":
case "mouseleave":
setHoveredNote(null);
case "click":
addCard(note);
if (bubbles) { // hover 상태 처리
setHoveredNote(note);
}
break;
default:
break;
}
}
const onClick = (event) => eventHandler(event);
const onMouseOver = (event) => eventHandler(event);
const onMouseOut = (event) => eventHandler(event);
return (
<Source
onClick={onClick}
onMouseOver={onMouseOver}
onMouseOut={onMouseOut}
className={
hoveredNote && hoveredNote.index === note.index ? "highlight" : null
}
>
{note.letters[0]}
</Source>
);
};
3. CSS 호버 사용
대안적으로, onMouseEnter 및 onMouseLeave 이벤트를 순수 CSS hover 효과로 대체할 수 있습니다. 이 방법은 이벤트 간의 잠재적인 충돌을 피하고, 두 번 탭하는 문제를 해결하는 데 도움이 될 수 있습니다.
const CardSource = ({ addCard, note, setHoveredNote, hoveredNote }) => {
return (
<Source
onClick={() => addCard(note)}
className={`source ${hoveredNote && hoveredNote.index === note.index ? "highlight" : ""}`}
>
{note.letters[0]}
</Source>
);
};
CSS 호버 효과를 사용하여 onMouseEnter 및 onMouseLeave 이벤트 없이도 원하는 기능을 구현할 수 있습니다.
결론
이러한 잠재적인 해결책이 여러분의 리액트 애플리케이션에서 모바일(iPhone)에서 두 번 탭해야만 동작하는 onClick 문제를 해결하는 데 도움이 되길 바랍니다. 다양한 접근 방식을 테스트하고 특정 사용 사례에 가장 잘 맞는 방법을 선택하는 것이 중요합니다. 데스크탑 및 모바일 장치 모두에서 원활하고 직관적인 사용자 경험을 제공하는 것은 애플리케이션의 성공에 매우 중요합니다.
코드를 더욱 탐구하고 실험해보고 싶다면, 제공된 코드샌드박스에서 작동하는 데모를 확인해 보세요: 여기를 클릭하세요.