[감정 일기장 만들기] localStorage를 일기 데이터베이스로 사용하기

미아·2023년 1월 12일
0

REACT

목록 보기
37/41

자바스크립트의 state가 갖는값은 휘발성 메모리이다.

=> 즉 우린 db가 필요하다!

이럴때 필요한게 Web Storage API

https://developer.mozilla.org/ko/docs/Web/API/Web_Storage_API


=> sessionStorage : 즉 웹브라우저가 꺼지면 데이터가 날아간다!@
=> localStorage : 데이터를 지워야만 사라지므로! 얘를 사용할 예정

더미데이터 사용하던 방식이 아닌, localStorage를 사용하는 방식으로 해볼것임!


브라우저>f12>localstorage>http~

  //localStorage 실습
  useEffect(() => {
    //저장할때는 setItem
    localStorage.setItem("item", 10);
    localStorage.setItem("item2", "20");
    //객체는 stringify => 문자열형태로 바꿔주는것 해줘야함!
    localStorage.setItem("item3", JSON.stringify({ value: 30 }));

    //꺼내올때는 getItem
    const item1 = localStorage.getItem("item");
    const item2 = localStorage.getItem("item2");
    const item3 = localStorage.getItem("item3");
    console.log({ item1, item2, item3 }); // console.log찍을때 보기 불편할거같으면 객체형태로!
  }, []);
  //local Storage에 한번 들어간 값은 지워지지않음 , 우클릭 delete 하면 지워짐
  //기본적으로 localStorage에 들어가는 값는 문자열로 바껴서 들어감

=> 즉 number타입으로 꺼내올때는 parseInt로 바꿔줘야하고
=> 객체를 넣었다면 JSON.parse()로 직렬화된 객체를 다시 자바스크립트객체로 바꿔야함

dummydata 지우고 localStorage 이용해 저장해보기!


컴포넌트가 mount 되었을때 localStorage에 있는 값 꺼내서 dataState의 기본값으로 사용하기

app.js

  • 우리는 newState가 바뀔때마다 localStorage의 데이터에 넣어주면 된다!
import React, { useEffect, useReducer, useRef } from "react";
import "./App.css";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "./pages/Home";
import New from "./pages/New";
import Edit from "./pages/Edit";
import Diary from "./pages/Diary";

const reducer = (state, action) => {
  let newState = [];
  switch (action.type) {
    case "INIT": {
      return action.data;
    }
    case "CREATE": {
      newState = [action.data, ...state];
      break;
    }
    case "REMOVE": {
      newState = state.filter((it) => it.id !== action.targetId);
      break;
    }
    case "EDIT": {
      newState = state.map((it) =>
        it.id === action.data.id ? { ...action.data } : it
      );
      break;
    }
    default:
      return state;
  }
  //1️⃣우리는 newState가 변화할때마다 localStorage의 데이터 넣어주면 됨
  localStorage.setItem("diary", JSON.stringify(newState));
  return newState;
};
// CreateContext - data 공급
export const DiaryStateContext = React.createContext();
// onCreate, onRemove, onEdit 전달
export const DiaryDispatchContext = React.createContext();

// const dummyData = [
//   {
//     id: 1,
//     emotion: 1,
//     content: "오늘의 일기 1번",
//     // 구하는 가장 쉬운 방법은 console.log(new Date().getTime())
//     date: 1673224084848,
//   },
//   {
//     id: 2,
//     emotion: 2,
//     content: "오늘의 일기 2번",
//     date: 1673224084849,
//   },
//   {
//     id: 3,
//     emotion: 3,
//     content: "오늘의 일기 3번",
//     date: 1673224084850,
//   },
//   {
//     id: 4,
//     emotion: 4,
//     content: "오늘의 일기 4번",
//     date: 1673224084851,
//   },
//   {
//     id: 5,
//     emotion: 5,
//     content: "오늘의 일기 5번",
//     date: 1673224084852,
//   },
// ];

function App() {
  const [data, dispatch] = useReducer(reducer, []);
  const dataId = useRef(0); //id는 useRef 훅으로 만든다

  //2️⃣얘는 아직 저장이 안된것이므로, application에만 남아있음(dispatch사용전까지)
  //useEffect -> 컴포넌트가 mount 되었을때(즉 빈배열) localStorage에 있는 값 꺼내서 dataState의 기본값으로 사용하기
  useEffect(() => {
    const localData = localStorage.getItem("diary");
    // localData가 있을수도, 없을수도(처음 접속한경우)
    if (localData) {
      const diaryList = JSON.parse(localData).sort(
        //직렬화로 값 바꿔주고
        (a, b) => parseInt(b.id) - parseInt(a.id)
      ); //내림차순 정렬, 최신순
      dataId.current = parseInt(diaryList[0].id) + 1; //가장 최근+1
      console.log(diaryList);
      console.log(dataId);

      //✔️ 완전 중요
      dispatch({ type: "INIT", data: diaryList });
    }
  }, []);
  // 이건 시간 ms로 구하는법
  console.log(new Date().getTime());

  /*dispatch 함수 필요한경우*/
  //CREATE
  const onCreate = (date, content, emotion) => {
    dispatch({
      type: "CREATE",
      data: {
        //받아야 하는 항목 : date, content, emotion, id!(여기는 작성자가 없다.)
        date: new Date(date).getTime(), // 커서 올렸을때 보라색으로 뜨면 () 포함임
        content,
        emotion,
        id: dataId.current,
      },
    });
    dataId.current += 1;
  };
  //REMOVE
  const onRemove = (targetId) => {
    dispatch({
      type: "REMOVE",
      targetId,
    });
  };
  //EDIT
  const onEdit = (date, content, emotion, targetId) => {
    dispatch({
      type: "EDIT",
      data: {
        id: targetId, // 얘 빼고 다 바꾸는거
        date: new Date(date).getTime(),
        content,
        emotion,
      },
    });
  };

  return (
    <DiaryStateContext.Provider value={data}>
      <DiaryDispatchContext.Provider value={{ onCreate, onEdit, onRemove }}>
        <BrowserRouter>
          <div className="App">
            <Routes>
              <Route path="/" element={<Home />} />
              <Route path="/new" element={<New />} />
              <Route path="/diary/:id" element={<Diary />} />
              <Route path="/edit/:id" element={<Edit />} />
            </Routes>
          </div>
        </BrowserRouter>
      </DiaryDispatchContext.Provider>
    </DiaryStateContext.Provider>
  );
}

export default App;
profile
새로운 것은 언제나 재밌어 🎶

0개의 댓글