데이터를 DB에 저장하여 가져올 수 있지만 프론트만 구현중이기 때문에 localStorage를 사용하여 데이터를 저장해보도록 하겠습니다.
localStorage는 Web Storage의 한 종류입니다. 먼저 Web Storage API를 알아보도록 하겠습니다.
브라우저에서 키/값 쌍을 쿠키보다 훨씬 직관적으로 저장할 수 있는 방법을 제공합니다.
http://example.com/app1/index.html
http://example.com/app2/index.html
다른출처 예시
http://example.com
http://www.example.com
http://myapp.example.com
출처 : mdn web docs
https://developer.mozilla.org/ko/docs/Web/API/WebStorage_API#web_storage%EA%B0%9C%EB%85%90%EA%B3%BC_%EC%82%AC%EC%9A%A9%EB%B2%95
저는 웹 브라우저가 꺼져도 데이터가 날라가는 것을 원하지 않기 때문에 localStorage를 사용하도록 하겠습니다.
App 컴포넌트에 아래 코드를 작성해줍니다.
useEffect(() => {
localStorage.setItem("key", 10);
}, []);
App 컴포넌트가 처음 렌더링 될 때 이 함수가 실행됩니다.
개발자 도구 > application 탭에서 데이터가 저장이 되었는지 확인해줍니다.
여러가지 자료형을 넣어보도록 하겠습니다.
useEffect(() => {
localStorage.setItem("item1", 10);
localStorage.setItem("item2", "10");
localStorage.setItem("item3", { value: 30 });
}, []);
객체는 스토리지가 받아들일 수 없는 값이기 때문에 Object object로 나타나 집니다. 그래서 직렬화를 사용하여 저장을 합니다.
localStorage.setItem("item3", JSON.stringify({ value: 30 }));
로컬 스토리지에서 값을 꺼내보도록 하겠습니다.
function App() {
useEffect(() => {
const item1 = localStorage.getItem("item1");
const item2 = localStorage.getItem("item2");
const item3 = localStorage.getItem("item3");
console.log({ item1, item2, item3 });
}, []);
item1을 저장할 때 number type으로 저장했지만 꺼내보니 문자열 입니다. 기본적으로 localStrage에 저장될 때는 문자열로 저장이 됩니다. 객체 또한 문자열로 꺼내졌습니다. parseInt와 JSON.pare를 사용하여 형 변환을 직접 해줘야 합니다.
function App() {
useEffect(() => {
const item1 = parseInt(localStorage.getItem("item1"));
const item2 = localStorage.getItem("item2");
const item3 = JSON.parse(localStorage.getItem("item3"));
console.log({ item1, item2, item3 });
}, []);
이제 실제 데이터를 localStrage에 담아보도록 하겠습니다.
import React, { useEffect, useReducer, useRef } from "react";
import "./App.css";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "./pages/Home";
import Edit from "./pages/Edit";
import New from "./pages/New";
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;
}
localStorage.setItem("diary", JSON.stringify(newState));
return newState;
};
export const DiaryStateContext = React.createContext();
export const DiaryDispatchContext = React.createContext();
function App() {
const [data, dispatch] = useReducer(reducer, []);
useEffect(() => {
const localData = localStorage.getItem("diary");
if (localData) {
const diaryList = JSON.parse(localData).sort(
(a, b) => parseInt(b.id) - parseInt(a.id)
);
dataId.current = parseInt(diaryList[0].id) + 1;
dispatch({ type: "INIT", data: diaryList });
}
}, []);
const dataId = useRef(0);
// CREATE
const onCreate = (date, content, emotion) => {
dispatch({
type: "CREATE",
data: {
id: dataId.current,
date: new Date(date).getTime(),
content,
emotion,
},
});
dataId.current += 1;
};
// REMOVE
const onRemove = (targetId) => {
dispatch({ type: "REMOVE", targetId });
};
// EDIT
const onEdit = (targetId, date, content, emotion) => {
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>
<Route path="/new" element={<New />}></Route>
<Route path="/edit/:id" element={<Edit />}></Route>
<Route path="/diary/:id" element={<Diary />}></Route>
</Routes>
</div>
</BrowserRouter>
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>
);
}
export default App;
reducer function 안에 마지막 줄에 newState를 localStorage에 저장을 합니다.
localStorage.setItem("diary", JSON.stringify(newState));
return newState;
App 컴포넌트 안에 useEffact를 사용하여 페이지가 렌더링 될 때 localStrage에 저장되어 있는 데이터를 꺼내서 dispatch 함수를 호출합니다.
useEffect(() => {
const localData = localStorage.getItem("diary");
if (localData) {
const diaryList = JSON.parse(localData).sort(
(a, b) => parseInt(b.id) - parseInt(a.id)
);
dataId.current = parseInt(diaryList[0].id) + 1;
dispatch({ type: "INIT", data: diaryList });
}
}, []);
잘 적용된 것을 확인할 수 있습니다.
리액트 공식 홈페이지
https://ko.legacy.reactjs.org/docs/react-api.html#reactmemo
해당 게시글은 인프런 강의
"한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지(이정환)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.