Language/React.js
[React] 감정일기장 프로젝트 : 웹 스토리지 연결과 배포 (완성)
JJcoding
2024. 10. 29. 11:19
웹 스토리지(Web Storage)
웹 브라우저 내장 DB
- 웹 브라우저에 기본적으로 내장되어 있는 데이터베이스
- 별도의 프로그램 설치가 필요 없다. 라이브러리 설치도 필요 없다.
- 그냥 자바스크립트 내장함수 만으로도 접근이 가능하다.
- 값을 저장 : localStorage.setItem(key, value)
- 값을 꺼냄 : localStorage.getItem(key)
- SessionStorage
- 브라우저 탭 별로 데이터를 보관한다.
- 탭이 종료되기 전에는 데이터를 유지한다. (새로고침 가능)
- 탭이 종료되거나 꺼지면 데이터를 삭제한다.
- LocalStorage
- 사이트 주소별로 데이터를 보관한다.
- 사용자가 직접 삭제하기 전까지는 데이터를 보관한다.
예시
// key값은 무조건 원시타입만 가능
// 값 저장
localStorage.setItem("test", "hello");
localStorage.setItem("person", JSON.stringify({ name: "다람쥐" }));
// 값 꺼내오기
console.log(localStorage.getItem("test"));
console.log(JSON.parse(localStorage.getItem("person")));
JSON.parse(undefined); // JSON.parse는 undefined나 null이 들어가면 에러를 뱉는다.
// 값 제거
localStorage.removeItem("test");
프로젝트에 적용하기
App.jsx
import "./App.css";
...생략
function reducer(state, action) {
let nextState;
switch (action.type) {
case "INIT":
return action.data;
case "CREATE": {
nextState = [action.data, ...state];
break;
}
case "UPDATE": {
nextState = state.map((item) =>
String(item.id) === String(action.data.id) ? action.data : item
);
break;
}
case "DELETE": {
nextState = state.filter((item) => String(item.id) !== String(action.id));
break;
}
default:
return state;
}
localStorage.setItem("diary", JSON.stringify(nextState));
return nextState;
}
...생략
function App() {
const [isLoding, setIsLoding] = useState(true);
const [data, dispatch] = useReducer(reducer, []);
const idRef = useRef(0);
useEffect(() => {
const storedData = localStorage.getItem("diary");
if (!storedData) {
setIsLoding(false);
return;
}
const parsedData = JSON.parse(storedData);
if (!Array.isArray(parsedData)) {
setIsLoding(false);
return;
}
let maxId = 0;
parsedData.forEach((item) => {
if (Number(item.id) > maxId) {
maxId = Number(item.id);
}
});
idRef.current = maxId + 1;
dispatch({
type: "INIT",
data: parsedData,
});
setIsLoding(false);
}, []);
... 생략
if (isLoding) {
return <div>데이터 로딩중입니다람쥐...</div>;
}
return (
...생략
);
}
export default App;
- dispatch로 data에 값을 넣다보니 로딩중 일 때 다른 컴포넌트에서 data를 사용하면 [] 빈 배열이 인식되어 오류가 발생한다. 이를 막기 위해 isLoding state를 선언하여 보완해주었다.
배포 준비
- 페이지 타이틀 설정하기
- 웹 브라우저 탭에 표시되는 페이지의 제목
- Favicon 설정하기
- 웹 브라우저 탭에 표시되는 페이지타이틀 옆 작은 아이콘
- 오픈 그래프 태그 설정하기
- 웹 사이트의 링크를 공유할 때 썸네일, 제목 등의 정보를 노출하는 것
- 프로젝트 빌드(Build)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>다람쥐 일기장</title>
<meta property="og:title" content="다람쥐 일기장" />
<meta property="og:description" content="나만의 작은 다람쥐 일기장" />
<meta property="og:image" content="/thumbnail.png" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
- 리액트는 싱글 페이지이기 때문에 title 태그에 값을 설정하면 어떤 페이지에서도 같은 값이 나온다.
usePageTitle.jsx
import { useEffect } from "react";
const usePageTitle = (title) => {
useEffect(() => {
const $title = document.getElementsByTagName("title")[0];
$title.innerText = title;
}, [title]);
};
export default usePageTitle;
- 만약 title을 바꾸고 싶다면 useEffect와 자바스크립트로 설정할 수 있다.
- usePageTitle 이라는 사용자 정의 훅을 만들어서 각 페이지에 적용할 수 있다.
배포
- 프로젝트 빌드하기 : 터미널에서 npm run build 입력한다.
- vercel에 들어가 회원가입 후 터미널에서 npm install -g vercel로 설치한다.
- vercel login 명령어를 통해 로그인을 한다.
> Success! GitHub authentication complete for 내 매일
Congratulations! You are now logged in. In order to deploy something, run `vercel`.
💡 Connect your Git Repositories to deploy every branch push automatically (<https://vercel.link/git>).
- 로그인이 성공된 후 터미널에 vercel을 입력하면 배포가 진행된다.
🔗 Linked to leejinjus-projects/emotion-diary (created .vercel and added it to .gitignore)
🔍 Inspect: <https://vercel.com/leejinjus-projects/emotion-diary/7FmFzNBozswBKb84a8HYCQrfFL1K> [2s]
✅ Production: <https://emotion-diary-2mcawvlvs-leejinjus-projects.vercel.app> [2s]
- Production에 적힌 주소로 들어가면 내가 만든 프로젝트 배포가 완료된 것을 볼 수 있다.
- 기능을 수정, 추가하고 난 뒤에도 똑같이 vercel 명령어를 입력하면 배포가 진행된다.
내가 만든 감정 일기장 완성!
https://emotion-diary-l05gdhbax-leejinjus-projects.vercel.app
다람쥐 일기장
나만의 작은 다람쥐 일기장
emotion-diary-l05gdhbax-leejinjus-projects.vercel.app
출처 : 한입 크기로 잘라먹는 리액트