=> 즉 우린 db가 필요하다!
https://developer.mozilla.org/ko/docs/Web/API/Web_Storage_API
=> sessionStorage : 즉 웹브라우저가 꺼지면 데이터가 날아간다!@
=> 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()로 직렬화
된 객체를 다시 자바스크립트
객체로 바꿔야함
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;