웹
한글 입력 시 중복 요청 이슈와 해결 방법
이지호_tech
2025. 4. 15. 14:44
한국어처럼 조합형 문자를 웹에서 입력할 때, 의도치 않게 중복 요청이 발생하는 경우가 자주 있다. 특히 React 환경에선 이 문제가 더 자주 보이는데, 원인과 해결 방법을 클라이언트, 훅, 서버 단에서 정리해봤다.
🧩 왜 한글 입력 시 중복 요청이 발생할까?
1. 조합형 언어의 특성
- 한글은 자음과 모음을 조합해 글자를 만든다. 예: ㄱ + ㅏ = 가
- IME(Input Method Editor)가 입력 중간 상태를 관리하면서 하나의 글자 입력에 여러 이벤트가 발생함
- 영어는 키보드를 누르면 바로 글자가 입력되지만, 한글은 조합 과정이 있어 조합 시작 → 변경 → 완료 등의 중간 단계를 거침
2. React의 이벤트 처리 방식
- React는 입력 이벤트를 상태 변화로 감지하고 리렌더링함
- 한글 입력 중간 상태에서도 이벤트가 발생해 의도치 않게 여러 번 렌더링 또는 요청이 발생할 수 있음
- 특히 Enter 키 입력과 한글 조합 완료 시점이 겹치면 중복 요청이 일어나는 현상이 자주 발생
🛡 중복 요청을 막는 방법
1. 클라이언트에서 방어 (메시지 전송, 검색 등)
const isSubmittingRef = useRef(false);
const handleSubmit = async () => {
if (isSubmittingRef.current) return;
isSubmittingRef.current = true;
await sendMessage();
setTimeout(() => {
isSubmittingRef.current = false;
}, 500);
};
- useRef로 요청 중 여부를 추적해 중복 요청 방지
- 빈 메시지는 아예 요청 자체를 막음
- 500ms 정도의 타임아웃으로 연속 요청 억제
2. useChat 훅에서 개선
- 최근 1초 이내에 동일한 메시지 전송 차단
- Content-Type을 application/json; charset=UTF-8로 설정해 한글 인코딩 문제 방지
- 전송 상태를 여러 ref로 분리 관리해 안정성 확보
- 디버깅을 위한 로그 추가로 문제 추적 용이
const existingMessage = chat.messages.find(
msg => msg.isUser &&
msg.message === message &&
Date.now() - new Date(msg.createdAt).getTime() < 1000
);
또한 나는 MSW를 사용하고 있어서, 핸들러(Mock Server)까지 개선해 주었다.
- 중복 메시지 감지 로직 추가
- 동일한 내용이 1초 이내에 들어오면 기존 응답을 재사용
if (existingMessage && existingMessage.modelReply) {
console.log('Detected duplicate message request, returning existing message:', existingMessage.message_id);
return HttpResponse.json({
user_message: existingMessage,
model_reply: existingMessage.modelReply
});
}
사용자의 연속적인 입력 중 마지막 입력 이후 일정 시간(예: 500ms) 동안 아무 이벤트가 없을 때만 요청을 보내는 방식으로
Debounce개념으로 처리해주었다. (마지막 입력 이후 일정 시간 대기 후 요청 허용)
한글 입력 중 중복 요청 방지엔 debounce 방식이 더 자연스럽고 적절하다.
throttle은 실시간 제어나 주기적 업데이트 등에 더 적합하다.
한글 입력 시 발생하는 중복 요청 이슈는 IME의 이벤트 처리 방식과 React의 상태 관리 방식 사이의 미묘한 차이에서 비롯된다. 조합형 언어의 특성을 감안하지 않으면 중복 요청, 중복 렌더링, 이상 동작이 발생할 수밖에 없다.