사용자의 입력값을 받는 검색 기능을 개발하고 있었다.
검색 기능에서 엔터를 눌렀을 때, 검색(돋보기 아이콘) 아이콘 클릭, 연관 검색어 및, 최근 검색어 클릭 이 3가지를 고려해서 개발을 진행했었는데,
QA 할 때는 분명 문제가 발생하지 않았는데, amplitude를 각 이벤트마다 삽입해주는 과정에서 문제가 발생했다.
(QA를 몇번이고 했기에.. 분명 문제가 없었는데…)
문제는 한글로 입력하고 키보드 이벤트(onKeyUp, onKeyDown)를 발생시키면 최근 검색어에 해당 입력값이 2개가 생긴다는 것이다.
(정상이라면 1개가 생겨야 한다.)
검색(돋보기 아이콘) 아이콘 클릭이나 연관 검색어 및 최근 검색어를 클릭해서 클릭 이벤트(onClick)를 발생시키면 최근 검색어에 해당 입력값 및
연관 검색어, 최근 검색어가 1개만 생긴다.
즉, 클릭 이벤트에서는 해당 문제가 발생하지 않지만 키보드 이벤트에서는 발생한다.
필자는 맥북 프로에서 크롬 브라우저를 사용하고, 로컬 환경이었다.
해당 문제를 해결하기 위해 구글에서 검색을 진행했고, 해당 문제를 겪은 사람들도 많았는데 IE 브라우저를 사용하는 사람, 크롬을 사용하는 사람들도 있다.
나의 문제와 다른 사람들이 겪은 문제를 종합적으로 생각해봤을 때 브라우저 문제는 아닌듯 하다.
많은 사람들이 추측? 예상? 하고 필자 또한 생각했던 부분이 영어와 한글의 차이였다.(영어는 한 글자에 1byte, 한글은 한 글자에 2byte)
한 글자의 byte 차이에 따른 문제가 아닐까 조심스레 추측해본다.(다른 문제를 의심해 볼 수도 있지만)
re-rendering 문제였다면, 키보드 이벤트가 영어를 입력했을 때도 두 번 또는 re-rendering 되는 회수 만큼 실행이 되었어야 한다고 생각을 했다.
그리고는 2byte이기 때문에 키보드 이벤트가 두 번 실행된것이라고 판단을 내렸다.
검색 결과의 해결방법 중 키보드 이벤트 함수를 재실행되지 않도록 막는 함수를 만드는 것이 딱 맞는 해결방법이라 생각이 들었고
필자의 코드에 적용하여 해결을 했다.
<Component
onKeyDown = {
(event) => {
if (event.key === 'Enter') {
키보드 이벤트 발생 시 작동 될 비즈니스 로직
}
}
}
/>
위 코드가 기존 코드
아래코드가 해결방법을 적용한 코드
function renderBreak(time) {
let continue = true;
return (func: any) => {
if (!continue) {
return;
}
continue = false;
func();
setTimeout(() => {continue = true}, time);
}
}
export default () => {
const renderBreakFunc = renderBreak(1000);
return (
<Component
onKeyDown = {
(event) => {
if (event.keyCode === 13) {
renderBreakFunc(() => {
키보드 이벤트 발생 시 작동 될 비즈니스 로직
})
}
}
}
/>
)
}
한글의 한 글자당 2byte로 인해 두 번 실행(재실행) 되려고 한다면 재실행 되지 않도록 조건문으로 브레이크를 걸어주는 방법이다.