React에서 로컬스토리지 연결하기

React에서 영화 찜(하트) 기능을 만들면서 로컬스토리지(localStorage)에 배열을 안전하게 저장하고 꺼내는 방법, 그리고 || "[]"를 쓰는 이유와 함께 정리했습니다.


1. || "[]"를 추가한 이유

  • 로컬스토리지에서 값을 꺼낼 때
    localStorage.getItem("WatchList")는 저장된 값이 없으면 null을 반환합니다.
  • null을 바로 JSON.parse에 추가했을 경우
    JSON.parse(null)null을 반환해서 에러는 안 나지만,
    undefined"undefined" 같은 잘못된 값이 들어가면 에러가 납니다.
  • 빈 배열로 안전하게 시작하기
    localStorage.getItem("WatchList") || "[]"처럼 써주면,
    값이 없을 때 항상 빈 배열 문자열로 대체되어 JSON.parse("[]")[]를 반환합니다.

2. 안전하게 로컬스토리지 배열을 꺼내는 코드

const savedList = localStorage.getItem("WatchList") || "[]";
let watchList = [];
try {
  watchList = JSON.parse(savedList);
  if (!Array.isArray(watchList)) watchList = [];
} catch (e) {
  watchList = [];
}
  • 값이 없거나, 잘못 저장된 경우에도 무조건 배열로 만들어줍니다.
  • 이렇게 하면 .some(), .filter() 등 배열 메서드를 안전하게 사용 가능합니다.

3. 구현 코드

import React, { useEffect, useState } from "react";
import pinkHeart from "../../imgs/pinkheart.png";
import greyHeart from "../../imgs/greyheart.png";

const Ranking = ({ movie }) => {
  const [isClicked, setIsClicked] = useState(false);

  // 컴포넌트가 처음 나타날 때, 이 영화가 찜 목록에 있는지 확인
  useEffect(() => {
    const savedList = localStorage.getItem("WatchList") || "[]";
    let watchList = [];
    try {
      watchList = JSON.parse(savedList);
      if (!Array.isArray(watchList)) watchList = [];
    } catch (e) {
      watchList = [];
    }
    const found = watchList.some((item) => item.id === movie.id);
    setIsClicked(found);
  }, [movie.id]);

  // 하트 버튼 클릭 시
  const handleClick = () => {
    const savedList = localStorage.getItem("WatchList") || "[]";
    let watchList = [];
    try {
      watchList = JSON.parse(savedList);
      if (!Array.isArray(watchList)) watchList = [];
    } catch (e) {
      watchList = [];
    }

    if (isClicked) {
      // 이미 찜한 상태: 제거
      const myList = watchList.filter((item) => item.id !== movie.id);
      localStorage.setItem("WatchList", JSON.stringify(myList));
      setIsClicked(false);
    } else {
      // 찜하지 않은 상태: 추가
      const newList = [...watchList, movie];
      localStorage.setItem("WatchList", JSON.stringify(newList));
      setIsClicked(true);
    }
  };

  const heartImg = isClicked ? pinkHeart : greyHeart;

  return (
    <div>
      <p>{movie.title}</p>
      <img src={heartImg} onClick={handleClick} alt="찜하기" />
    </div>
  );
};
  • 하트는 isClicked 값에 따라 분홍/회색이 바뀝니다.
  • 찜 추가/제거 시 로컬스토리지와 상태를 모두 바꿔야 화면이 즉시 반영됩니다.

정리

  • 로컬스토리지에서 배열을 꺼낼 때는 항상 || "[]"를 붙입니다.
  • 이렇게 하면 값이 없거나 잘못된 값이 들어가도 에러 없이 빈 배열로 시작할 수 있습니다.
  • 배열 메서드를 쓸 때도 안전하다.
  • 키 이름(예: "WatchList")은 항상 일관되게 사용해야 합니다.
728x90

'무비넷' 카테고리의 다른 글

웹앱 성능 최적화  (0) 2025.09.02
[React] 클릭시 이미지 변경하기  (0) 2025.05.28
[React]리액트 타입 연결  (0) 2025.05.23
프롭스 연결하기  (0) 2025.05.22
프로젝트 시작  (0) 2025.05.08