gocamp - 북마크 기능

ryan·2022년 9월 14일
0
post-custom-banner

개요

야영장 지도의 중요 기능 중 하나인 북마크와 링크 공유 버튼 구현 과정을 담았다.

기능 구현

북마크

  • 현재 프로젝트에 백엔드 개발자가 없기 때문에, Web Storage(Local Storage)를 사용하였다.
  • 아래 이미지에서 북마크 버튼을 클릭하면 북마크가 등록되며, 하단 네브바(브라우저에서는 내 정보)에서 북마크를 누르면 등록한 북마크를 리스트 형식으로 볼 수 있는 형태를 구상했다.

북마크 등록

  • 북마크 리스트는 전역 상태로 관리하도록 설계하였으며, 북마크 버튼을 누를 때마다 setter 함수를 통해 local Storage에 북마크 정보가 저장되며, local storage값을 반환한다.
  • setter함수는 다음과 같다.
    - 우선, localStorage key를 검사한 뒤, key가 없다면, setItem으로 초기값 등록
    • key가 있다면, 중복된 값이 있는지 확인하고 중복됐다면 기존 값 삭제
    • 중복되지 않았다면 값을 추가하여 다시 setItem
    • localStorage 값을 반환.
// 북마크 클릭 시 동작하는 함수
const bookmarkHandler = () => {
  // spotInfo(야영지 정보)를 인수로 보냄
  // controlWebStorage에서 반환된 값을 bookmark라는 전역 함수에 등록
  setBookmark(controlWebStorage(spotInfo));
};


// utills/controlStorage.js
const controlWebStorage = (spotInfo) => {
  let bookmarkList = JSON.parse(localStorage.getItem("bookmark"));
  const bookmarkObj = {
    id: spotInfo.contentId,
    addr: spotInfo.addr1,
    name: spotInfo.facltNm,
    x: spotInfo.mapX,
    y: spotInfo.mapY,
  };

  // 처음 북마크를 등록할 때
  if (!bookmarkList) {
    return localStorage.setItem("bookmark", JSON.stringify([bookmarkObj]));
  }

  // 이미 등록된 북마크를 다시 클릭했을 때
  if (bookmarkList.filter((e) => e.id === spotInfo.contentId)[0]) {
    const exceptExistValue = bookmarkList.filter((e) => e.id !== spotInfo.contentId);
    localStorage.setItem("bookmark", JSON.stringify(exceptExistValue));
  } else {
    // 기존 북마크 배열에 새로운 북마크 등록
    bookmarkList.push(bookmarkObj);
    localStorage.setItem("bookmark", JSON.stringify(bookmarkList));
  }
  return JSON.parse(localStorage.getItem("bookmark"));
};
  • bookmark의 값을 dependency로 등록한 useEffect에 useState를 사용하여, 이미 등록된 북마크인 경우에는 '등록됨'이라는 텍스트를 표시하고 아이콘 또한 변경.

모든 상세 정보 페이지는 params로 id값을 주기 때문에 id값과 local Storage값을 비교한 뒤 filter 적용

결과 (북마크 등록)

북마크 리스트

  • 북마크 리스트를 보고 북마크를 누르면 해당 위치로 이동하고 관련 정보를 띄우는 작업
  • gocamp의 모든 행동은 params가 적용되기 때문에, 북마크된 야영장 리스트를 클릭할 경우, 파람스를 전달하고 페이지를 이동시킴.
bookmark.js
const Bookmark = () => {
  const bookmark = useRecoilValue(bookmarkState);
  const navigate = useNavigate();
  
  const bookmarkClickHandler = (e) => {
    navigate({
      pathname: "/maps",
      search: `?${createSearchParams({
        id: e.id,
        x: e.x,
        y: e.y,
      })}`,
    });
  };

  return (
    <section css={bookmarkContent}>
        <ul>
          {bookmark ? (
            bookmark.map((e) => {
              return (
                <li
                  onClick={() => {
                    bookmarkClickHandler(e);
                  }}
                  key={e.id}>
                  <h4>{e.name}</h4>
                  <p>{e.addr}</p>
                </li>
              );
            })
          ) : (
            <p>아직 등록된 북마크가 없습니다.</p>
          )}
        </ul>
    </section>
  );
};

결과 (북마크 클릭)

모바일

브라우저

profile
프론트엔드 개발자
post-custom-banner

0개의 댓글