[checky] 한글 입력 중 Enter로 태스크가 두 번 생성되던 문제 해결기

2026. 1. 12. 23:26·📋 프로젝트/☄️ 트러블 슈팅
728x90
반응형

| 서론

안녕하세요 팡일입니다.

 

오늘은 투두 서비스의 태스크 입력 UX를 개선하는 과정에서 마주했던 한글 입력(IME) 관련 트러블슈팅에 대해 이야기해보려고 합니다. 태스크를 빠르게 연속으로 추가할 수 있도록 입력 컴포넌트를 유지하는 UX를 구현하던 중, 예상치 못한 중복 태스크 생성 문제가 발생했습니다.

 

겉보기에는 단순한 Enter 입력 처리 문제처럼 보였지만, 실제 원인은 한글 입력기의 조합(composition) 방식에 있었습니다. 이번 포스트에서는 해당 문제가 어떻게 발생했는지, 원인을 어떻게 파악했으며, 어떤 방식으로 해결했는지를 정리해보려고 합니다.

 

비슷한 입력 UX를 구현하고 있거나, 한글 입력을 다루는 프론트엔드 개발자에게 참고가 되었으면 합니다.

 

 

 

| 문제 인식: 한글 입력 중 Enter, 두 번의 제출 (As-Is)

문제는 다음과 같은 상황에서 발생했습니다.

 

태스크 추가 후 입력 컴포넌트를 닫지 않고 유지하여, 사용자가 연속으로 태스크를 추가할 수 있도록 UX를 개선했습니다. 그러나 특정 한글 입력 패턴에서 태스크가 두 개 생성되는 현상이 발견되었습니다.

 

1) 정상 동작 사례

입력: 테스트
Enter 입력 → 태스크 1개 생성
  • 이미 완성된 한글 단어
  • 문제 없이 정상 동작

2) 비정상 동작 사례

입력: ㅇㅇㅇ
Enter 입력 → 태스크 2개 생성
결과:
ㅇㅇㅇ
ㅇ
  • 마지막 글자가 아직 조합 중인 상태
  • Enter 입력 시 submit 로직이 두 번 실행됨

처음에는 submit 함수가 중복 호출되는 로직 오류를 의심했지만, 코드를 확인해보니 명시적인 중복 호출은 존재하지 않았습니다.

 

 

 

| 원인 분석: IME 조합(Composition) 이벤트의 존재

이 문제의 핵심 원인은 한글 입력기의 조합 방식(IME, Input Method Editor) 에 있었습니다.

 

한글은 영문과 달리, 입력 과정에서 다음과 같은 조합 단계를 거칩니다.

  1. 자음 입력 (ㅇ) → 아직 확정되지 않은 조합 상태
  2. 이후 모음 입력 가능성 존재
  3. 조합 중 Enter 입력 시
    → 조합 종료 이벤트 + Enter 이벤트가 연속으로 발생

즉, React 입장에서는 다음과 같은 일이 벌어집니다.

  • onKeyDown(Enter)가 두 번 처리됨
  • submit 로직이 의도치 않게 두 번 실행됨

반면, 테스트처럼 이미 조합이 끝난 문자열은 이러한 문제가 발생하지 않았습니다.

 

 

 

| 목표 설정: 조합 중 Enter는 제출로 처리하지 않는다 (To-Be)

이 문제를 해결하기 위해 다음과 같은 목표를 설정했습니다.

  • 한글 조합 중 Enter 입력은 submit으로 처리하지 않는다
  • 조합이 완료된 이후의 Enter만 유효한 제출로 인식한다
  • 기존 UX(연속 입력, 버튼 클릭 제출, blur 처리)는 유지한다

이를 위해 입력 상태를 명확히 구분할 수 있는 기준이 필요했고, 그 해답은 composition 이벤트였습니다.

 

 

 

| 실행: IME 조합 상태 추적을 통한 해결

1) 1단계: 조합 상태를 저장할 ref 생성

const isComposingRef = useRef(false);

 

렌더링과 무관한 입력 상태이므로 state가 아닌 ref를 사용했습니다.

 

2) 2단계: composition 이벤트 처리

<input
  value={taskInput}
  onChange={(e) => setTaskInput(e.target.value)}

  onCompositionStart={() => {
    isComposingRef.current = true;
  }}
  onCompositionEnd={() => {
    isComposingRef.current = false;
  }}

  onKeyDown={(e) => {
    if (e.key === "Enter") {
      if (isComposingRef.current) return;
      handleSubmit();
    }
  }}
/>
  • onCompositionStart → 조합 시작
  • onCompositionEnd → 조합 종료
  • 조합 중 Enter 입력은 무시

3) 3단계: submit 로직은 그대로 유지

const handleSubmit = () => {
  if (!taskInput.trim()) return;

  onAddTask(taskInput);
  setTaskInput("");
};

submit 로직 자체를 수정하지 않고, 입력 이벤트 단계에서 차단하는 방식으로 문제를 해결했습니다.

 

 

 

| 결과: 입력 UX 안정성 확보

이번 개선을 통해 다음과 같은 결과를 얻을 수 있었습니다.

  • 한글 조합 중 Enter 입력 → submit 발생하지 않음
  • 조합 완료 후 Enter 입력 → 정상 submit
  • 연속 태스크 입력 UX 유지
  • 마우스 클릭 제출, blur 처리 모두 정상 동작

또한, 이 방식은 한글뿐 아니라 일본어, 중국어 등 IME 기반 입력 환경 전반에 대응 가능한 구조가 되었습니다.

 

 

 

| 마치며

이번 트러블슈팅을 통해 다시 한 번 느낀 점은, 입력 UX는 단순히 키 이벤트만 처리해서는 충분하지 않다는 것이었습니다.

 

특히 한국 서비스를 개발하는 프론트엔드 개발자라면, IME 조합 이슈는 언젠가 반드시 마주치게 됩니다. 겉으로는 정상처럼 보이지만, 실제 사용자 입력 흐름에서는 전혀 다른 문제가 발생할 수 있습니다.

 

“동작하는 코드”를 넘어서, “실제 사용자의 환경에서도 안전한 코드”를 고민하는 것이 프론트엔드 개발자의 중요한 역할이라는 점을 다시 한 번 깨닫는 경험이었습니다.

 

앞으로도 이런 작은 UX 이슈들을 놓치지 않고 기록해보려고 합니다.

728x90
반응형

'📋 프로젝트 > ☄️ 트러블 슈팅' 카테고리의 다른 글

[트러블슈팅] DB는 바뀌는데 UI는 그대로였다, TanStack Query 캐시 동기화 해결  (0) 2026.02.01
'📋 프로젝트/☄️ 트러블 슈팅' 카테고리의 다른 글
  • [트러블슈팅] DB는 바뀌는데 UI는 그대로였다, TanStack Query 캐시 동기화 해결
pangil_kim
pangil_kim
기록을 통해 지속적인 성장을 추구합니다.
  • pangil_kim
    멈추지 않는 기록
    pangil_kim
  • 전체
    오늘
    어제
  • 📝 글쓰기
      ⚙️ 관리

    • 분류 전체보기 (405) N
      • 💻 개발 (176) N
        • ※ 참고 지식 (9)
        • 🦕 React (13)
        • 🎩 Next.js (25)
        • 📘 TypeScript (4)
        • 📒 JavaScript (8)
        • 🟩 Node.js (7)
        • 📀 MySQL (24)
        • 🌸 Spring Boot (5)
        • 👷 SveleteKit (24)
        • 🩵 Flutter (11)
        • 🌀 Dart (2)
        • 🌈 CSS (5)
        • 🔸Git (1)
        • 🔥 Firebase (4)
        • 🧑🏻‍💻 코테 (29) N
        • 🕸️ 알고리즘 (4)
        • 🌤️ AWS (1) N
      • 📋 프로젝트 (4) N
        • ☄️ 트러블 슈팅 (2) N
        • 🧑🏻‍💻 서비스 소개 (2)
      • ✍🏻 회고 (52) N
        • ☀️ 취준일지 (6) N
        • 🍀 우테코 (32)
        • 👋 주간회고 (1) N
      • 📰 정보 공유 (12)
      • 🧑🏻‍💻 개발자라면? (1)
      • 🏫 한동대학교 (153)
        • Database (15)
        • Software Engineering (18)
        • EAP (22)
        • 일반화학 (26)
        • 25-1 수업 정리 (19)
        • Computer Networking (36)
        • OPIc (2)
        • 미술의 이해 (15)
  • 최근 글

  • 인기 글

  • 태그

    네트워킹
    csee
    typeScript
    CCM
    날마다 솟는 샘물
    예배
    한동대학교
    찬양
    웹 프론트엔드 8기
    주일
    고윤민교수님
    전산전자공학부
    우테코 8기
    날솟샘
    부트캠프
    컴네
    QT
    프리코스
    웹개발
    우아한테크코스
    computer networks and the internet
    글로벌리더십학부
    GLS
    어노인팅
    프론트엔드
    설교
    우테코
    묵상
    데이터베이스
    FE
  • 최근 댓글

  • 250x250
  • hELLO· Designed By정상우.v4.10.4
pangil_kim
[checky] 한글 입력 중 Enter로 태스크가 두 번 생성되던 문제 해결기
상단으로

티스토리툴바