모바일에서의 React onClick 문제 해결하기

리액트: 모바일(iPhone)에서 onClick 이벤트 동작 시 2번 탭이 필요한가요? 리액트로 작업하다가 모바일(iPhone)에서 클릭 가능한 컴포넌트의 onClick 이벤트가 한 번이 아니라 두 번 탭해야만 동작하는 현상을 경험한 적이 있나요? 이 블로그 포스트에서는 이 문제를 탐구하고 해결할 …

title_thumbnail(모바일에서의 React onClick 문제 해결하기)

리액트: 모바일(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 문제를 해결하는 데 도움이 되길 바랍니다. 다양한 접근 방식을 테스트하고 특정 사용 사례에 가장 잘 맞는 방법을 선택하는 것이 중요합니다. 데스크탑 및 모바일 장치 모두에서 원활하고 직관적인 사용자 경험을 제공하는 것은 애플리케이션의 성공에 매우 중요합니다.

코드를 더욱 탐구하고 실험해보고 싶다면, 제공된 코드샌드박스에서 작동하는 데모를 확인해 보세요: 여기를 클릭하세요.

참고 자료 : 

reactjs

Leave a Comment