문제 상황 : 검색중인 화면을 만들면서 최근 검색어를 추가하면 좋겠다 싶었다. localstorage를 사용하면 좋을 것 같았다.
로컬스토리지에 값을 올릴 때는 배열이나 객체처럼 생긴 string 만 올라간다.
getFromLocal
const getFromLocal = () => {
const history = localStorage.getItem('currentSearch');
return history ? JSON.parse(history) : [];
};
saveToLocal
const saveToLocal = (history: string[]) => {
localStorage.setItem('currentSearch', JSON.stringify(history));
};
이렇게 로컬에서 배열을 가져오는 함수와 로컬에 저장해주는 함수를 만들었으니까 페이지가 이동할 때 검색어가 로컬에 있는 값에 포함되는지 아닌지를 확인하고 history 배열에 키워드를 넣어준 다음 saveToLocal 을 이용해 로컬에 넣어주면 된다
const handleMovePage = () => {
if (query.trim()) {
const history = getFromLocal();
if (!history.includes(query)) {
history.push(query);
saveToLocal(history);
}
navigate(`/home/search/${query}`);
}
};
이렇게 로컬에 검색한 키워드 넣는 것 까지는 성공!
그럼 이제 검색 페이지에서 로컬에서 가져온 다음에 출력해줘야 하겠다.
getFromLocal을 재사용해서 배열을 history 상수로 가져온 다음 map 으로 키워드와 인덱스를 받아 return 해주면 된다.
여기서 시행착오가 조금 있었는데 배열이어서 forEach 로 돌렸더니 안 나오는 것이었다. 생각해보면 당연했다! forEach는 리턴값이 없고 각 값을 순회하면서 콜백함수를 실행한 뿐이었고 map은 각 값에 콜백함수를 실행하면서 실행결과를 리턴해주는 메서드였다.
forEach는 array[index] = currentValue *2 같은 콜백함수를 실행시키게 하면 원본이 바뀌고 map은 원본은 유지, 해당 콜백함수를 실행한 결과 배열을 새로 반환해주는 애들이었다!!
{history.map((keyword: string, index: number) => {
return <div key={index}>{keyword}</div>;
})}
그렇기 때문에 각 값마다 새로운 엘리멘트를 반환해야 하는 지금 시점에 forEach는 반환값이 없기 때문에 부적절하고 map을 사용해야 했다. 🧐✨
forEach에서 map으로 바꿨으니 return 을 넣어주는 것도 잊지 말자.