인턴 사전과제로 최근 검색어 기능에 대해서 다음과 같은 요구사항을 받았다.
따라서 나는 다음과 같이 구현하려고 생각했다.
검색어 입력하고 엔터를 누를 시 localStorage에 recent-keywords
의 키에 해당하는 값에 { 검색어1: 시간1, 검색어2: 시간2, ... }
의 객체로 저장한다.
다음 번에 다시 돋보기 버튼을 눌러서 검색 페이지를 여는 순간 localStorage의 recent-keywords
키에 해당하는 값을 JSON.parse()
해서 실제 객체(A
라고 하자)로 얻어낸다.
for (const key in A)
를 통해서 모든 검색어들을 순회하며 현재 시간과 비교했을 때 10분 이상 차이가 난다면 그러한 검색어들은 필터링을 해주고 남은 것들만 최근 검색어로 띄운다.
그런데, 로직은 문제가 없는 것 같았으나 3번 과정을 실행했을 때 모든 검색어들이 다 10분 이상 차이가 나서 최근 검색어가 뜨지 않았다. 그래서 검색어들과 연결된 시간들을 console.log()
로 찍어보며 문제를 찾아냈다.
원인은, 분명히 내가 저장할 때 시간을 console.log()
로 찍었을 때도 한국시간으로 저장이 되는 걸 확인했는데, 나중에 localStorage에서 꺼내서 그걸 console.log()
로 찍으니 미국 시간으로 찍혀서 현재 시간과 엄청난 차이가 났기 때문이다.
엔터를 눌렀을 때 로컬스토리지에 해당 검색어를 현재 시간과 함께 저장하는 함수를 보면서 어떻게 해결했는지 설명해 보겠다.
import { useState } from "react";
import { useRouter } from "next/router";
const storeRecentKeyword = (keyword: string) => {
if (typeof window !== "undefined") {
const keywords = localStorage.getItem("recent-keywords");
// 유효 기간 10분으로 설정
const date = new Date();
date.setSeconds(date.getSeconds() + 600);
if (keywords) {
const keywords_JSON = JSON.parse(keywords);
keywords_JSON[keyword] = date;
localStorage.setItem("recent-keywords", JSON.stringify(keywords_JSON));
} else {
localStorage.setItem(
"recent-keywords",
JSON.stringify({ keyword: date })
);
}
}
};
/*
import { useState } from "react";
import { useRouter } from "next/router";
const storeRecentKeyword = (keyword: string) => {
if (typeof window !== "undefined") {
const keywords = localStorage.getItem("recent-keywords");
// 유효 기간 10분으로 설정
const date = new Date();
date.setSeconds(date.getSeconds() + 600);
if (keywords) {
const keywords_JSON = JSON.parse(keywords);
*/
!! 여기서 date를 그대로 넣어주지 않고 date를 문자열로 바꿔서 넣어줌 !!
keywords_JSON[keyword] = new String(date);
/*
localStorage.setItem("recent-keywords", JSON.stringify(keywords_JSON));
} else {
localStorage.setItem(
"recent-keywords",
*/
!! 마찬가지로 date를 문자열로 바꿔서 넣어줌 !!
JSON.stringify({ keyword: new String(date) })
);
}
}
};
위처럼 현재 시간을 저장할 때 그대로 넣어주지 않고 문자열로 변환한 후에 그 문자열을 넣어주었다. 따라서, 나중에 꺼내 볼 때는 다시 Date로 변환한 후에 현재 시간과 비교를 하게 된다.
// keywords는 최근 검색어들을 저장하고 있는 전역 상태이다.
/*
const [keywords, setKeywords] = useRecoilState(recentKeywordState);
useEffect(() => {
if (typeof window !== "undefined") {
const recentKeywords = localStorage.getItem("recent-keywords");
if (
recentKeywords &&
JSON.stringify(keywords) !== JSON.stringify(recentKeywords)
) {
const JSONKeywords = JSON.parse(recentKeywords);
setKeywords([]);
*/
for (const key in JSONKeywords) {
const now = new Date();
!! 여기서 Date 형식으로 변환한 다음에 현재 시간과 비교 !!
if (new Date(JSONKeywords[key]) >= now)
setKeywords((prev) => prev.concat(key));
}
/*
setKeywords((prev) => {
const temp = Array.from(prev);
return temp.reverse().slice(0, 30);
});
}
}
}, []);
날짜를 저장할 때 안전빵(?)으로 하려면 문자열로 저장해 논 다음에 꺼내볼 때 다시 Date 형식으로 바꿔서 보는 방법도 사용해 볼 수 있다!