
Today I Learn📖
- 고양이 사진 검색기 (강의)
- main.js와 App.js를 분리하는 이유 (추가 학습)
https://도메인/api/cats/keywords?q={keyword}
: ${keyword}에 해당하는 검색어를 조회https://도메인/api/cats/search?q={keyword}
: ${keyword}에 해당하는 고양이 사진 검색
- 기본 마크업 구조
Keyword에서 입력 발생 ->Header로 콜백 ->Header에서App으로 콜백- 올라온 입력값을
App에서Keywords에 내려서 화면에 그림Keywords에서 선택된 값을App이 받음 ->App이SearchResults로 내려서 얘가 화면에 그림
Keyword.js에서 keyup 이벤트 감지하기Keyword.js에서 발생한 입력을 Header.js -> App.js으로 콜백시켜서 값 전달App.js에서 가지고 있고, setState를 통해 상태 업데이트 하고, 그 값을 SuggestKeywords로 전달SuggestKeywords에서 화면에 렌더링 시키기 (추천키워드 존재할 경우에만 .style.display = 'block' 되도록 처리)SuggestKeywords에서 보여준 추천 키워드 중 하나 선택하면 Click 이벤트 발생textContent로 선택 내용 꺼내오기suggestKeywords에 넘겨주고, header 상태 변경 & 그리기
.textContent: 요소의 텍스트만 뽑아옴 (HTML 태그는 무시하고, 태그 속의 텍스트만 반환).innerHTML: HTML 태그를 포함해 구조, 스타일, 텍스트 전체를 다 반환
App.js의 suggestKeywords에서 SuggestKeywords컴포넌트로 cursor = -1 넘기기 (기본값 -1, 위아래로 움직이면 +-1씩 값 변경)
keydown 이벤트를 통해 커서 움직이게 하기
// SuggestKeywords.js
window.addEventListener('keydown'
, (e) => {
if ($suggest.style.display != 'none') {
const { key } = e;
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 === 'ArrowDown') {
const nextCursor = this.state.cursor + 1;
this.setState({
...this.state,
cursor: nextCursor > this.state.keywords.length - 1 ? 0 : nextCursor;
})
} else if (key === 'Enter') {
onKeywordSelect(this.state.keywords[this.state. cursor]);
}
debounce.js 생성
// debounce.js
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);
};
}
App.js 속 header의 onKeywordInput에 debounce 걸기
-> onKeywordInput: debounce(...내용, delay값)으로 전체 감싸기
데이터가 자주 바뀌지 않는다면, 매번 API 호출하는 대신 스토리지에 캐싱해서 사용하는 것도 괜찮은 방법 !
-> 네트워크 최적화 가능(네트워크가 자주 불리는 걸 막기 때문)
로컬 스토리지: 캐시를 날리는 작업도 해야해서 귀찮을 수 있음세션 스토리지: 페이지 나가기 전까지만 저장되어있음캐시값이 있으면 ? 저장된 캐시값 사용 : API 호출컴포넌트를 선언하는 쪽 / 실행하는 쪽으로 역할 분리함으로써 가독성, 재사용성, 유지보수성 향상되기 때문
main.js: 프로그램이 시작되는 곳, 프로그램의 작동 환경 및 설정 담당, 실행되는 쪽App.js: 화면에 보이는 부분들을 구상 및 UI 요소 조합, 선언되는 쪽
실행은 main.js에서 하기 때문에, 조건에 따라 App.js 내의 다양한 컴포넌트를 불러오고 조합하는 방식으로 상황에 맞는 여러 화면을 구성할 수 있음
main.js는 환경 및 설정, App.js는 화면 구성에 관한 컴포넌트이기 때문에 각각 역할이 명확함
-> 각 역할이 명확하니 가독성이 올라감
-> App.js의 재사용이 쉬워짐 ex)테스트 필요시 App.js만 따로 확인하기
-> 문제 발생시 원인 파악에 용이함
-> 업데이트나 기능 추가가 필요할 경우, 각 역할에 맞는 부분을 디벨롭하면 됨
추천 검색어를 보여주고, 선택하는 기능을 구현하는 방법에 대해 배웠다.
저번 시간에 배웠던 디바운스와 스토리지를 활용해 API를 적게 호출해서 최적화를 이루는 방법에 대해서도 살펴봤다.
추천 검색어 기능을 배우기 전에는 무작정 엄청 어려운 기능일 거라고 생각했었는데, 오늘 실습을 쭉 따라가니까 엄청 어렵지는 않은 느낌이었다 ㅎㅎ
나도 저 기능을 많이 사용하고 편하다고 느끼는 만큼, 다른 프로젝트에서 구현해보고 싶은 기능이다!