프로그래머스 2020 Dev-Matching : 웹 프론트엔드 과제 복기
https://github.com/woohyeonjo/ilovecat
회원가입 또는 결제 정보를 입력하는 중에 새로고침을 눌러 작성한 정보가 모두 없어지거나 쇼핑몰을 이용하면서 제품 상세 정보로 들어갔다가 뒤로가기를 눌렀을 때 스크롤이 처음으로 돌아가서 불편했던 경험이 있을 것이다. 새로고침이나 뒤로가기를 하게되면 웹 페이지를 다시 불러와 랜더링을 하는데 이전의 입력 정보 또는 스크롤 정보는 유지되지 않기 때문에 발생하는 문제다.
그렇다면 유지하고 싶은 정보를 따로 저장한다면 해결될 일 아닌가? 그런데 어디에 저장할 것인가? 그것이 문제다.
모든 이용자들의 일시적인 정보를 서버에 저장하는 것은 특별한 경우를 제외하고는 좋은 생각이 아닌 것 같다. 큰 저장 용량이 필요한 것도 아니고 오래 보관해야하는 데이터도 아니다. 이런 필요성에서 클라이언트에도 데이터를 저장할 수 있는 공간(브라우저에 저장한다.)이 생긴게 아닐까 싶다.
과거에는 쿠키
가 있었고 HTML5 부터는 Web Storage
라는 더 좋은 저장소가 생겼다. Web Storage API는 두 가지 저장소를 제공한다.
기본적으로 데이터는 Key
-Value
형태로 저장된다. 사용은 굉장히 간단하다. API에서 제공하는 매서드를 사용하기만 하면 된다.
이번 프로젝트의 요구사항에는 다음과 같은 사항이 있었다.
우선 저장소는 SessionStorage를 사용하기로 결정했다. 마지막 검색 결과 화면의 유지는 세션 종료시까지만 유지하면 되기 때문이다. LocalStorage를 사용하면 직접 저장소에서 삭제하기 전 까지 데이터가 유지될 것인데 그럴 필요는 없기 때문이다.
// sessionStorage.js
function getItem(key) {
const value = sessionStorage.getItem(key);
if(key === 'data') return value === null ? null : JSON.parse(value);
else return value === null ? [] : JSON.parse(value);
}
function setItem(key, value) {
if(value === null || value === undefined) return;
const toJson = JSON.stringify(value);
sessionStorage.setItem(key, toJson);
}
export { getItem, setItem };
최근 검색어
와 마지막 검색 결과
에 대한 분기가 생겼고... 다시 보니 좀 부끄러운 코드다.다음으로 마지막 검색 결과 화면이 유지되도록 하려면 마지막으로 검색한 결과 데이터를 가지고 있어야한다. 따라서 검색할 때 결과 데이터를 계속 저장하도록 하였다.
export default class App {
constructor($target) {
const keywords = getItem('keywords');
const data = getItem('data');
const searchingSection = new SearchingSection({
$target,
keywords,
onSearch: async keyword => {
loading.toggleSpinner();
const response = await api.fetchCats(keyword);
if(!response.isError){
setItem('data', response.data);
resultsSection.setState(response.data);
loading.toggleSpinner();
} else {
error.setState(response.data);
}
},
onRandom: async () => {
loading.toggleSpinner();
const response = await api.fetchRandomCats();
if(!response.isError){
setItem('data', response.data);
resultsSection.setState(response.data);
loading.toggleSpinner();
} else {
error.setState(response.data);
}
}
});
const resultsSection = new ResultsSection({
$target,
data,
onClick: data => {
detailModal.setState(data);
},
onScroll: async () => {
loading.toggleSpinner();
const response = await api.fetchRandomCats();
if(!response.isError){
const beforeData = getItem('data');
const nextData = beforeData.concat(response.data);
setItem('data', nextData);
resultsSection.setState(nextData);
loading.toggleSpinner();
} else {
error.setState(response.data);
}
}
});
...
}
}
searchingSection
에 전달하는 onSearch
, onRandom
함수에 fetchAPI
호출에 대한 응답 데이터(검색 결과 데이터)를 저장하는 코드를 작성하였다.resultsSection
의 매개변수로 넘겨져 화면에 랜더링 된다.
잘 보고 갑니다! 그런데 setItem('data', response.data); 이렇게 매번 검색결과를 저장한다고 했을 때, 새로고침해도 페이지를 유지할 수 있는 건 알겠는데, 무한스크롤이 적용된 페이지라면 어떻게 하는 게 좋을까요? 의견 듣고 싶습니다.