[AI 감성 일기장] LocalStorage를 활용한 데이터 영속성 구현

Dev Log

로컬 스토리지를 활용하여 사용자의 다크모드 설정, 일기 데이터, AI 답장을 저장하고 관리하는 기능을 구현했다.

페이지를 새로고침하거나 재방문해도 사용자의 데이터가 유지된다.

다크모드 설정 저장

설정 불러오기

애플리케이션 로드 시 로컬 스토리지에서 사용자의 마지막 다크모드 설정을 불러온다.

const ThemeProvider = ({ children }: ThemeProviderProps) => {
  const loadDarkModeSetting = () => {
    const storedDarkModeSetting = localStorage.getItem("darkMode");
    return storedDarkModeSetting ? JSON.parse(storedDarkModeSetting) : false;
  };

  const [isDarkMode, setIsDarkMode] = useState(loadDarkModeSetting);
  // ...
};

 

설정 저장

다크모드 상태가 변경될 때마다 로컬 스토리지에 저장한다.

useEffect(() => {
  const body = document.querySelector("body");
  isDarkMode ? body?.classList.add("dark") : body?.classList.remove("dark");
  localStorage.setItem("darkMode", JSON.stringify(isDarkMode));
}, [isDarkMode]);

사용자가 선택한 다크모드 설정이 페이지 새로고침 후에도 유지된다.

 

일기 데이터 저장

Reducer를 통한 데이터 관리

일기 데이터의 생성, 수정, 삭제 작업이 발생할 때마다 로컬 스토리지에 저장한다.

function reducer(state: DiaryType[], action: ActionType) {
  let nextState;
  switch (action.type) {
    case Action.INIT:
      return action.data;
    case Action.CREATE: {
      nextState = [action.data, ...state];
      break;
    }
    case Action.UPDATE: {
      nextState = state.map((item) =>
        String(item.id) === String(action.data.id) ? action.data : item
      );
      break;
    }
    case Action.DELETE: {
      nextState = state.filter((item) => String(item.id) !== String(action.id));
      break;
    }
    default:
      return state;
  }
  localStorage.setItem("diary", JSON.stringify(nextState));
  return nextState;
}

변경된 상태를 반환하기 전에 로컬 스토리지에 저장하여 데이터 동기화를 보장한다.

 

초기 데이터 불러오기

애플리케이션 시작 시 로컬 스토리지에서 저장된 일기 데이터를 불러와 초기 상태를 설정한다.

useEffect(() => {
  const storedData = localStorage.getItem("diary");
  if (!storedData) {
    setIsLoading(false);
    return;
  }
  const parsedData = JSON.parse(storedData);
  if (!Array.isArray(parsedData)) {
    setIsLoading(false);
    return;
  }

  // 새로운 일기의 ID를 위해 최대 ID 계산
  let maxId = 0;
  parsedData.forEach((item) => {
    if (item.id > maxId) {
      maxId = item.id;
    }
  });
  idRef.current = maxId + 1;

  dispatch({
    type: Action.INIT,
    data: parsedData,
  });
  setIsLoading(false);
}, []);

저장된 데이터의 최대 ID를 계산하여 새로운 일기 생성 시 ID 충돌을 방지한다.

 

AI 답장 데이터 저장

답장 불러오기

일기 상세 페이지 진입 시 해당 일기의 AI 답장이 있는지 확인하고 표시한다.

useEffect(() => {
  const diaries = getDiaries();
  const currentDiary = diaries.find((diary) => diary.id === id);
  if (currentDiary && currentDiary.gptAnswer) {
    setGptAnswer(currentDiary.gptAnswer);
    setHasReceived(true);
  }
}, [id]);

 

답장 저장

AI 답장을 받으면 해당 일기 데이터에 답장을 추가하고 로컬 스토리지를 업데이트한다.

const handleClickAPICall = async () => {
  try {
    setIsLoading(true);
    const message = await CallGPT({
      prompt: JSON.stringify(content),
    });
    setHasReceived(true);
    const parsedMessage = JSON.parse(message);

    if (parsedMessage && parsedMessage.answer) {
      const diaries = getDiaries();
      const diaryIndex = diaries.findIndex((diary) => diary.id === id);

      if (diaryIndex !== -1) {
        diaries[diaryIndex].gptAnswer = parsedMessage.answer;
        localStorage.setItem("diary", JSON.stringify(diaries));
      }
      setGptAnswer(parsedMessage.answer);
    }
  } catch (error) {
    console.error(error);
  } finally {
    setIsLoading(false);
  }
};

 

사용자가 일기 상세 페이지를 재방문할 때 이전에 받은 AI 답장을 다시 볼 수 있다.

 

'Dev Log' 카테고리의 다른 글

[PeaNutter] TypeScript에서 버튼 클릭 이벤트 타입 에러 해결  (0) 2025.11.08
[PearNutter] 소셜미디어 앱 마이그레이션 계획  (0) 2025.11.07
[AI 감성 일기장] GPT API를 활용한 AI 답장 기능 구현  (0) 2025.11.07
[AI 감성 일기장] Tailwind CSS와 Context API를 활용한 다크모드 구현  (0) 2025.11.07
[AI 감성 일기장] Diary 페이지 일기 상세보기 기능 구현  (0) 2025.11.07
'Dev Log' 카테고리의 다른 글
  • [PeaNutter] TypeScript에서 버튼 클릭 이벤트 타입 에러 해결
  • [PearNutter] 소셜미디어 앱 마이그레이션 계획
  • [AI 감성 일기장] GPT API를 활용한 AI 답장 기능 구현
  • [AI 감성 일기장] Tailwind CSS와 Context API를 활용한 다크모드 구현
고견
고견
개발 자국 남기기
  • 고견
    개발자국
    고견
  • 전체
    오늘
    어제
    • 분류 전체보기 (157) N
      • Frontend (29)
        • Next.js (16)
        • JavaScript (7)
      • CS (19) N
        • 자료구조 (9)
        • 알고리즘 (5)
        • 운영체제 (4) N
        • 네트워크 (1) N
      • TIL (93)
      • Dev Log (16)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

    CS
    Pages Router
    배열
    Next.js
    cs50
    ai 감성 일기장
    타입 좁히기
    자료구조
    함수 타입
    C
    App Router
    앱 라우터
    제네릭
    인터페이스
    useState
    바닐라 자바스크립트
    generic
    memory
    알고리즘
    문자열
    Trouble Shooting
    페이지 라우터
    emotion diary
    typescript
    algorithm
    트러블 슈팅
    Spa
    javascript
    react
    클래스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고견
[AI 감성 일기장] LocalStorage를 활용한 데이터 영속성 구현
상단으로

티스토리툴바