HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
👻
개발 기록
/
📑
강의 정리
/
📑
고양이 사진 검색기 만들기
📑

고양이 사진 검색기 만들기

Created
Sep 10, 2021 04:39 AM
Type
VanillaJS기본역량강화
Mento
로토
Created By

요구사항

  • 검색 키워드를 입력하면 추천 검색어 API를 이용해 추천 검색어 보여주세요.
    • 검색어 입력 후엔 엔터키 등 별도의 추가 액션이 없어도 검색어 목록을 보여줘야 해요.
  • 키보드, 마우스로 추천 검색어를 선택할 수 있게 해주세요.
    • esc를 누르면 검색창이 닫힙니다.
    • 키보드 위, 아래를 누르면 추천 검색어 하이라이트가 옮겨지고 엔터를 누르면 하이라이트 처리된 검색어가 반영됩니다.
    • 마우스로는 클릭한 검색어가 반영됩니다.
  • 검색된 결과에 따라 고양이 사진이 화면에 렌더링 되어야 합니다.
notion image
💡
HTML 구조를 어떻게 짜야할지 고민해야 나중에 혼선이 없음.

요점 정리

동작 원리

  • 키보드를 누르면 onKeywordInput함수를 호출하여 api를 request함.
  • 이후 setState로 현재 상태 + 키워드를 nextState로 전달함.
  • 현재 상태에 있는 keywords로 suggestKeywords함수를 호출함.
  • suggestKeywords에서 onKeywordSelect를 호출함.
  • onKeywordSelect는 keyword를 매개변수로 받아 내부 함수의 setState를 그림.
  • SuggestKeyword.js는 innerHTML로 검색 결과를 보여줌.
💡
state의 변화가 필요한 모든 곳에 setState의 상태값을 변경해주어야 함.

검색 결과 키보드로 조작하기

  • App.js의 suggestKeywords 컴포넌트 initalState에 cursor를 추가함. 기본값은 -1.
  • window의 addEventListener로 keydown이 일어나면 숫자를 가감하며 cursor의 위치를 조절함.
  • Enter를 누르면 cursor의 위치한 키워드를 onKeywordSelect의 파라미터로 전달, 함수 호출함.
window.addEventListener("keydown", (e) => { if ($suggest.style.display !== "none") { //arrow down, arrow up, enter를 입력했을 때 각각 동작해야 함. const { key } = e; if (key === "ArrowDown") { const nextCursor = this.state.cursor + 1; this.setState({ ...this.state, cursor: nextCursor > this.state.keywords.length - 1 ? 0 : nextCursor, }); } else if (key === "ArrowUp") { const nextCursor = this.state.cursor - 1; this.setState({ ...this.state, cursor: nextCursor < 0 ? this.state.keywords.length - 1 : nextCursor, }); } else if (key === "Enter") { onKeywordSelect(this.state.keywords[this.state.cursor]); } } });

검색 결과 그리기

  • 키워드 선택시 추천 검색어 지우기 → fetch 함수 끝에 keywords: [] 추가
  • 검색을 하면(엔터, 추천 검색어 클릭) fetchCatsImage 함수 호출.
  • fetchCatsImage는 api를 호출해 data를 받아온 후 해당 데이터로 setState를 함.
  • 만약 data가 제대로 들어왔다면 searchResult 컴포넌트에 해당 image data를 파라미터로 setState를 전달함.
  • searchResult.js에선 받은 state로 innerHTML을 이용해 이미지를 그림.

debounce - 사용자 검색 지연

  • 사용자의 오타를 대비함.
  • App.js에서 header 컴포넌트의 onKeywordInput 함수 통채로 debounce를 적용함.
export default function debounce(fn, delay) { let timer = null; return function () { const context = this; const args = arguments; clearTimeout(timer); timer = setTimeout(() => { fn.apply(context, args); }, delay); }; }