React Context API와 LocalStorage로 상태 관리

2025. 4. 23. 15:19·React

1. Context API란?

Context API는 React에서 제공하는 전역 상태 관리 도구입니다.
컴포넌트 트리 전체에서 props를 일일이 넘기지 않고도 데이터를 공유할 수 있도록 도와줍니다.

 

언제 사용할까?

  • 여러 컴포넌트에서 동일한 상태나 함수를 사용할 때
  • 상위 컴포넌트에서 하위 컴포넌트로 깊게 상태를 전달해야 할 때 (prop drilling 문제가 발생할 경우)

Context는 우리가 직접 "세션처럼" 저장해줘야 한다!

Context는 브라우저 메모리에만 존재

즉, 새로고침 시 모든 값이 초기화되기 때문에 상태를 유지하려면

우리가 직접 로컬 스토리지에 저장하고 불러오는 로직을 구현

Context는 세션처럼 동작하지 않기 때문에 세션의 역할을 직접 코딩
Context에 저장된 데이터를 브라우저 저장소에 수동으로 넣어주는 방식이 필요

 


1- 1 Context API + LocalStorage ( sessionStorage )연동 구조

Context API로 전역 상태를 관리하면서 그 상태를 LocalStorage와 연동

  • 브라우저를 새로고침해도 상태가 유지
  • 앱 전역에서 어디서든 쉽게 상태를 참조하고 수정
  • Redux 같은 외부 상태 관리 라이브러리 없이도 충분히 유연한 상태 관리를 구현
Context API는 브라우저를 새로고침하면 값이 사라지기 때문에,
데이터를 유지해야 하는 경우 반드시 LocalStorage나 sessionStorage 같은 저장소와 연동해서 사용해야 한다

1- 2 localStorage vs sessionStorage

HTML5에서는 클라이언트에서 정보를 저장할 수 있도록

localStorage와 sessionStorage라는  Web Storage API를 제공

 

두 저장소 모두 브라우저에 데이터를 key-value 형태로 저장하는 기능을 제공하지만,

=> 차이점은  유지 시간 입니다.

항 localStorage sessionStorage
유지 기간 영구 저장 (삭제 전까지) 세션 단위 (탭/브라우저 종료 시 삭제)
저장 위치 브라우저 로컬 브라우저 세션 (탭마다 별도)
페이지 새로고침 유지됨 유지됨
탭 닫기 유지됨 삭제됨
주 사용 용도 사용자 설정, 테마, 장기 데이터 보관 로그인, 임시 폼 데이터, 단기 세션 유지

 

로컬 스토리지(LocalStorage)란?

LocalStorage는 브라우저에서 제공하는 키-값 형태의 영속 저장소

페이지를 닫거나 브라우저를 종료하더라도 저장된 데이터는 유지!!!

 

주요 특징

  • 도메인별로 분리된 저장 공간
  • 페이지를 닫아도 데이터가 유지됨
  • 문자열 형태로만 저장 가능
  • 브라우저마다 다르지만 보통 5MB 정도의 저장 공간 제공
// 저장
localStorage.setItem("key", "value");

// 불러오기
const value = localStorage.getItem("key");

// 삭제
localStorage.removeItem("key");

// 전체 삭제
localStorage.clear();

 

주의사항

  • 보안에 민감한 정보는 저장 X.
  • 일부 브라우저 환경에서는 로컬 스토리지를 비활성화할 수 있다!
  • 동기적으로 동작하므로 대량의 데이터를 다룰 경우 성능 문제가 발생할 수 있다!!

 

 

세션 스토리지 (sessionStorage) 란 ?

  • 현재 브라우저 세션(탭, 창)이 유지되는 동안만 데이터 저장
  • 세션이 종료되면(탭 닫기, 브라우저 종료) 저장된 데이터는 삭제됨
  • 다른 탭에서는 공유되지 않음 (탭마다 독립적임)
  • 사용법은 localStorage와 동일
sessionStorage.setItem("key", "value");
const data = sessionStorage.getItem("key");
sessionStorage.removeItem("key");
sessionStorage.clear();

 

로그인 후 특정 탭에서만 유지되는 정보
입력 중인 폼 데이터 임시 저장
로그인 상태 관리 (짧은 시간 동안만 유효)

 

 

! 세션 추가설명

HTTP는 무상태(Stateless) 프로토콜이기 때문에, 매 요청마다 연결이 끊어지는 구조
클라이언트가 상태를 유지하기 위해 쿠키를 사용하며, 이때 jsessionid 같은 세션 ID를 발급.
sessionStorage는 클라이언트 측에서 세션 동안만 데이터를 보관하기 위한 수단
서버가 새로운 세션을 발급하면 이전 세션은 무효화되며, 로그아웃 시 새로운 세션 ID로 갱신

1-3 실제 코드로 북마크 시스템 구현하기

북마크 기능을 Context API와 LocalStorage를 연동하여 새로고침해도 사라지지 않도록 구현!

 Bookmark에 로컬 스토리지 + 로드 상태 관리 흐름

1. 타입 정의 // store_bookmark

interface BookMarkContextType {
  books: Book[];                  // 북마크 도서 배열
  loaded: boolean;                // 로컬스토리지에서 데이터 로드 여부
  registBookMark: (book: Book) => void;
  removeBookMark: (isbn: string) => void;
  clearBookMark: () => void;
}
  • loaded: boolean 추가
  • 로컬 스토리지에서 데이터를 불러온 상태인지 여부를 추적하기 위한 상태

2. 로컬스토리지 불러오기 (처음 한 번만 실행)

const [books, setBooks] = useState<Book[]>([]);
const [loaded, setLoaded] = useState(false); // 로딩 상태 초기값 false

useEffect(() => {
  const store = localStorage.getItem("bookmark"); // key: "bookmark"
  if (store) {
    try {
      setBooks(JSON.parse(store)); // JSON 파싱 후 저장
    } catch {
      setBooks([]); // 파싱 실패 시 빈 배열로 초기화
    }
  }
  setLoaded(true); // 로딩 완료 표시
}, []);
  • useEffect(() => {}, [])로 처음 마운트될 때 한 번만 실행
  • 로컬스토리지에 데이터가 있으면 파싱하여 books에 저장
  • 완료 후 loaded를 true로 변경 → 이후 저장 가능하게 만듦

3. books 상태가 바뀔 때 저장

useEffect(() => {
  if (loaded) {
    localStorage.setItem("bookmark", JSON.stringify(books));
  }
}, [books, loaded]);
  • books가 바뀔 때마다 실행됨
  • 단, loaded === true일 때만 로컬스토리지에 저장
    → 처음 로딩 중 덮어쓰기 방지

4. useMemo로 context value 캐싱

const returnValue = useMemo(
  () => ({
    books,
    registBookMark,
    removeBookMark,
    clearBookMark,
    loaded
  }),
  [books, loaded]
);
  • books, loaded를 의존성에 포함
  • loaded가 변경되어도 컨텍스트 갱신이 반영되도록 설정

5. 로딩 중 표시 처리 (초기 상태 대응) // App / bookMark // pages

const { clearBookMark, books, loaded } = useBookMarkContext();

if (!loaded || books == null) {
  return (
    <div className={styles.bookList}>
      <p style={{ textAlign: "center", padding: "item" }}>
        즐겨 찾기 목록을 불러오는 중
      </p>
    </div>
  );
}
  • 로딩이 끝나지 않았을 때(loaded === false)
  • 또는 books가 null일 경우
    → "즐겨찾기 목록을 불러오는 중" 메시지를 렌더링하여 사용자에게 로딩 중임을 안내
loaded는 로컬 스토리지에서 데이터를 불러왔는지를 판별하기 위한 키
loaded 없이 저장하면 초기 빈 배열이 저장될 수 있음
useMemo에서 loaded를 의존성에 포함해야 제대로 반영됨
페이지에서도 loaded 체크하여 초기 로딩 상태 시 비어있는 UI 방지

 

'React' 카테고리의 다른 글

타입스크립트 사용법과 기본 타입 정리  (0) 2025.05.26
Context 알아보기  (0) 2025.04.22
TanStack Query (React Query) 알아보기  (0) 2025.04.21
Axios와 async/await  (2) 2025.04.16
React & Next.js 활용해보기 / CSR vs SSR  (1) 2025.04.14
'React' 카테고리의 다른 글
  • 타입스크립트 사용법과 기본 타입 정리
  • Context 알아보기
  • TanStack Query (React Query) 알아보기
  • Axios와 async/await
startfront
startfront
startfront 님의 블로그 입니다.
  • startfront
    startfront 님의 블로그
    startfront
  • 전체
    오늘
    어제
    • 분류 전체보기 (42) N
      • 프로젝트 (5) N
        • 프로젝트 해보기 (1) N
        • 디자인 알아보기 (2)
        • 프로젝트의 기본 (2)
      • 백엔드의 이해 (4)
      • React (14)
      • 프론트엔드 기본 (2)
        • Html (1)
        • Css (0)
        • JavaScript (1)
      • Cs기본지식 (14)
        • 알고리즘 (8)
        • 데이터베이스 (6)
      • Java (3)
        • Java의 이해 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
startfront
React Context API와 LocalStorage로 상태 관리
상단으로

티스토리툴바