일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- error
- CRUD w ReactQuery
- wanted-preonboarding-course
- TypeScript
- 회고
- 멀티프로세스
- CS
- refactoring
- 짝선배 짝후배 매칭 웹 개발 회고
- Spa
- teave
- 멀티스레드
- Today
- Total
깊고 넓은 삽질
프리온보딩 코스 회고록 마지막 | 디바운스바운스 두근대 들킬까바겁나 본문
09.27~ 09.28 검색창 구현 + 검색어 추천 기능 구현 (github repo https://github.com/wanted-team-11/pre-onboarding-assignment-week-5-1-team-11)
이번 과제 난이도는 바로 이전 과제에 비해 평이했다. 그래서 팀원들 각자 개인적으로 구현하고 취합하는 방식으로 진행했다.
검색어 추천 기능 구현
기업 과제 중 api 통신을 이용해 검색어 추천 기능을 구현할 때 겪은 일이다. 검색창에서 사용자가 검색어를 입력하면 실시간으로 입력한 값을 미리 api 쿼리로 날려 검색결과가 있는 검색어를 추천해주는 기능을 구현해야했다. 여기서 중요한 점은 api 호출을 최소화였다. 이를 위한 두 가지 전략이 있는데 api 캐싱과 디바운싱이다.
api 캐시와 디바운싱 구현
api캐시는 로컬 변수에 캐시를 선언해 해결했다.
디바운싱은 keyword라는 검색어 state에 의존하고 있는 useEffect의 클린업 함수로 clearTimeout을 호출한다. 이러면 검색어가 바뀔 때마다 useEffect가 실행되면서 기존에 있던 타이머가 클린업 함수 호출로 사라지게 된다.
추천단어에 포함되는 검색어 강조
추천어 배열을 map으로 반환하면서 각각 포함하고있는 검색어를 강조처리해야했다. 정규식을 써서 추천어 중 검색어만 strong 태그로 대체하고 싶었지만 replace함수의 반환값은 jsx가 아니라 string이었기 때문에 문제가 있었다. 그래서 map 내부에 추천어를 split(검색어)로 나누고 그 배열을 다시 map으로 반환해줬다.
const hightlightWord = (fullWord: string, highlight: string) => {
return (
<div>
{fullWord.split(highlight).map((e, i, arr) => {
return i < arr.length - 1 ? (
<>
{e}
<strong>{highlight}</strong>
</>
) : (
e
);
})}
</div>
);
};
키보드 방향키로 검색어 추천 이동하기
이 부분이 가장 많이 고민한 부분이다. 처음에는 추천 검색어들에 focus를 주려고 했다. 그런데 어렵기도 어려웠고 다른 포털사이트를 보니 focus는 여전히 검색어 input에 있고 검색어 추천 쿼리를 날리지 않은 채 input value값만 해당 추천어로 대치되고 있었다. 그래서 상태 값으로 선택된 index값을 가지고 해당 index와 추천어 리스트의 인덱스를 비교해 일치하는 요소의 배경색을 바꾸어 강조하는 것으로 선택을 구현했다.
그런데 키보드가 한국어 모드일 때 keydown event가 두 번 불리는 현상이 있었다. 검색해보니 한 글자를 입력할 때 두 개 이상의 입력을 요하는 언어권의 글자들에서 나타는 현상 같았다. 이는 이벤트 속성 중 isComposing으로 분기해서 해결했다. 한국어 모드일 때 처음 입력이 isComposing true로 오기 때문에 이를 걸러준다.
문제는 강조되는 추천어로 input value를 대체하면서 추천어 쿼리를 날리지 않아야 하는 것이다. 추천어 쿼리를 검색에 input의 onchange에 걸어놨기 때문에 애를 많이 먹었다. 결국 상태 값을 하나 더 만들고 방향키를 누를 때 상태를 toggle해 방향키를 누르는 것과 input을 직접 바꾸는 것을 분기했다.
여담
한 달간의 코스 과정이 끝났다. 온라인 상으로만 만나서 끝나도 별 감흥 없을 줄 알았는데 막상 끝나니 시원섭섭하다. 아쉬워서 디스코드를 서성이다가 나갔는데 모두 칼퇴근하셔서 머쓱했다. 나만 또 진심이었지,,이번 팀플을 통해 부끄러운 점이 참 많았다. 같은 말이라도 다르게 말하는 방장님에게 많이 배워간다. 부끄러움을 느꼈다는 것은 그만큼 성장했다는 뜻이겠다. 다음에 만난다면 더 나은 모습을 보여드려야지. 신세 많이 지고갑니다.