개발새발 로그

[2023-11-01] TIL - 검색기능을 배우면서(검색어 추천) 본문

카테고리 없음

[2023-11-01] TIL - 검색기능을 배우면서(검색어 추천)

이즈흐 2023. 11. 1. 20:02

 

 

오랜만에 TIL을 쓰게 되었다.

너무 바쁜 나머지 밀린 TIL이 너무 많다...히히

오늘부터 다시 배운 것들을 정리하고,

어려웠던 부분을 적어놓으면서 다시 실수하지 않도록 할 것이다.

 

📝오늘 배운 것

1. 검색어 추천 기능(API로 기능함)
2. 검색기능(API로 기능함)
3. 상,하 방향키로 검색어 추천 텍스트를 고르는 기능(변수 cursor 값 이용)
4. 너무 잦은 API요청은 SessionStorage 이용
5. 다바운싱 기법 모듈 사용

 

 

💡알게 된 것

1. 검색어 추천 기능을 배우면서 프론트 쪽에서 구현하지않고, 서버를 통해 API 요청으로 가능하다는 점을 알게 되었다.

 - 나는 원래 검색어 추천기능은 프론트쪽에서 모든 검색어 데이터를 들고와서 예전에 배운 트라이를 이용하는 것인가 생각했는데 서버쪽에서도 가능하다는 것을 알게 되었다.

 - 하지만 어차피 서버에서도 트라이 같은 알고리즘을 써야할 것이라 생각한다.

 

2. 너무 잦은 API가 일어날 때는 디바운싱 기법을 사용하고, 여기서 더 나아가 SessionStorage를 이용할 수 있다.

타이핑이 일어날 때마다 API요청이 일어나면 서버에 부담이 가게된다.

그러면 우리는 디바운싱기법을 사용해서 이를 해결한다.

하지만 검색어 추천과 같은 기능은 디바운싱 기법을 사용해도 delay 값을 크게할 수 없다.

왜냐하면 검색어 추천은 계속해서 추천을 해줘야하기 때문이다.

그래서 또 사용하는 것이 SessionStorage였다.

 

1. stroage.js 모듈 만들기

2. 컴포넌트에 세션 스토리지 전용 상태 (cache)를 만들고, getItem한다.

3. 타이핑이 일어날 때 해당 텍스트가 상태(cache)에 존재하면 그 값을 보내준다.

4. 타이핑이 일어날 때 해당 텍스트가 상태에 없다면 setItem해주고, 상태에도 저장해준다.

 

 

💢만났던 난관

1. 검색하는 input 요소와 검색어 추천을 보여주는 suggest 요소에서 이벤트 핸들러가 겹치는 현상

- 이 부분에서 input에 값을 입력하고 엔터를 치면 해당되는 이미지를 불러와야하고,

suggest요소에서 엔터를 눌러도 해당 되는 이미지를 불러와야했다.

- suggest는 input 요소에서 상,하 방향키를 누르면 suggest요소로 이동해야했기에 window.addEventListener를 해야했다.

- 그래서 만약 엔터를 누르게 되면 input과 suggest에 등록되었던 이벤트핸들러가 모두 호출되어 버그가 생기게 되었다.

 

해결 방법

input의 이벤트핸들러와

suggest의 이벤트 핸들러에 조건을 줘서

이벤트가 중복으로 일어나지 않도록 하면된다.

 

나는 input 요소에 

만약 suggest요소로 가기 위해 상,하 방향키가 입력되면 input의 포커싱을 해제해서 

input 요소의 이벤트 핸들러에 반응하지 않도록했다.'

  $keyword.addEventListener("keyup", (e) => {
    //만약 키워드를 선택하려고 방향키를 누른다면 keyword의 포커싱을 해제해서 enter 이벤트가 안먹히게함
    if (e.key === "ArrowDown" || e.key === "ArrowUp") {
      $keyword.blur();
    }

    if (e.key === "Enter") {
      onEnter();
    } else if (e.key !== "ArrowDown" && e.key !== "ArrowUp") {
      onKeywordInput(e.target.value);
    }
  });

 

그리고 suggest에서는 window에 이벤트가 등록되어있기 때문에 cursor라는 변수 값이 -1(초기화 상태)이 아닐 때만 반응하게 했다.

이를 통해서 input과 suggest의 Enter이벤트가 중복으로 일어나지 않았다.

 
 ...
 
 else if (e.key === "Enter" && cursor !== -1) {
        onKeywordSelect(keywords[cursor]);
}

...

 

 

 

728x90
반응형
LIST