문제

const moveTouch = useCallback((event: TouchEvent) => {
    event.preventDefault();
    event.stopPropagation();

    if (!canvasRef.current) {
      return;
    }
    const canvas: HTMLCanvasElement = canvasRef.current;

    let touch = event.touches[0];
    let mouseEvent = new MouseEvent("mousemove", {
      clientX: touch?.clientX,
      clientY: touch?.clientY,
    });

    canvas.dispatchEvent(mouseEvent);
  }, []);

터치 그림판 구현을 위하여 터치 이벤트를 마우스이벤트로 dispatch 해주는 함수를 만들어 리액트의 onTouchMove에 넣어주었는데,

모바일 뷰에서 터치로 그림을 그릴 수 없는 문제가 발생함

원인

touch 이벤트를 mouse 이벤트로 dispatch 해주는 과정에서 react의 이벤트 핸들러인 onMouseDown, onMouseMove 등으로는 event dispatch가 어려운 것으로 판단

터치이벤트마다 마우스이벤트와 같은 로직을 만들어줄 것인지, 아니면 위와같은 방식으로 dispatch해줄 것인지 고민하게 됨.

전자가 더 비효율적인 것 같다고 판단.

해결

  1. touch 이벤트를 mouse 이벤트로 dispatch 해주는 과정에서 react의 이벤트 핸들러인 onMouseDown, onMouseMove 등으로는 event dispatch가 어려운 것으로 판단되어 addEventListener, removeEventListener 사용을 통해 touch 이벤트를 mouse 이벤트로 dispatch해주는 데에 성공했습니다.
  2. mouse, touch 이벤트를 처리해주는 로직이 canvas 컴포넌트 안에 있는것이 적합하다고 판단했고, 해당 이벤트 처리 함수를 usePen과 useEraser 에서 사용하고 있기 때문에 canvas 컴포넌트에 해당 이벤트 처리함수들을 넣게 되었습니다.
  3. usePen과 useEraser가 같은 mousePosition 상태를 사용하고 있다고 판단되어, 이를 canvas 컴포넌트에서 선언해주고 props로 내려주게 되었습니다.
  4. mousemove, touchmove와 같은 렌더링을 자주 일으키는 함수들에만 useCallback을 사용했습니다.