프로젝트 준비하기
1. 요구사항 분석하기
2. 리액트 앱 만들기
3. 폰트 설정하기
4. 이미지 준비하기
1. 요구사항 분석하기
- Home 페이지
- New 페이지
- Diary 페이지
- Edit 페이지
2. 리액트 앱 만들기
> npm create vite@latest
3. 폰트 설정하기
// index.css
@import url("https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&family=Yeon+Sung&display=swap");
body {
font-family: "Nanum Pen Script";
margin: 0px;
}
4. 이미지 준비하기
src에 img 폴더를 생성하고, 사용하려는 이미지 파일들을 해당 폴더에 저장해서 사용
앱 구현하기
1. 페이징 라우팅
2. 글로벌 레이아웃 설정
3. 공통 컴포넌트 구현
4. 개별 페이지 및 복잡한 기능 구현
1. 페이징 라우팅
[리액트 라우터 설치]
> npm i react-router-dom
// main.jsx
(...)
import { BrowserRouter } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
// App.jsx
import { Routes, Route } from "react-router-dom";
import "./App.css";
import Home from "./pages/Home";
import New from "./pages/New";
import Diary from "./pages/Diary";
import Edit from "./pages/Edit";
import NotFound from "./pages/NotFound";
function App() {
return (
<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 />} />
<Route path="*" element={<NotFound />} />
</Routes>
</div>
);
}
export default App;
동적 경로의 종류
URL 파라미터 값 불러오기
import { useParams } from "react-router-dom";
const Diary = () => {
const { id } = useParams();
return (
<div>
<div>{id}번 일기</div>
</div>
);
};
export default Diary;
쿼리 스트링으로 값 불러오기
import { useSearchParams } from "react-router-dom";
const Home = () => {
const [searchParams, setSearchParams] = useSearchParams();
return (
<div>
<div>sort 타입은 {searchParams.get("sort")}</div>
</div>
);
};
export default Home;
2. 글로벌 레이아웃 설정
- index.css 에서 기본 폰트, body, root 스타일 적용
- App.css 에서 App 컴포넌트의 스타일 설정
3. 공통 컴포넌트 구현
버튼 컴포넌트 구현하기
날짜 입력 섹션 구현하기
일기 입력 섹션 구현하기
하단 버튼 섹션 구현하기
감정 이미지 선택 섹션 구현하기
4. 개별 페이지 및 복잡한 기능 구현
일기 관리 기능 만들기
// App.jsx
Home 페이지 구현하기
Diary 페이지 구현하기
New 페이지 구현하기
Edit 페이지 구현하기
최적화하기
웹 스토리지
로컬 스토리지
[ 데이터 생성/수정 ]
localStorage.setItem("key", value);
OR
localStorage.setItem("key", JSON.stringfy(value));
[ 데이터 꺼내기 ]
localStorage.getItem("key");
const rawData = localStorage.getItem("key");
if (rawData) {
const = JSON.parse(rawData);
}
[ 데이터 지우기 ]
localStorage.removeItem("key");
세션 스토리지
[ 데이터 생성/수정 ]
sessionStorage.setItem("key", value);
OR
sessionStorage.setItem("key", JSON.stringfy(value));
[ 데이터 꺼내기 ]
sessionStorage.getItem("key");
const rawData = sessionStorage.getItem("key");
if (rawData) {
const = JSON.parse(rawData);
}
[ 데이터 지우기 ]
sessionStorage.removeItem("key");
배포
페이지 제목 설정하기
리액트 앱은 브라우저에서 페이지를 동적으로 생성하기 때문에, 페이지 컴포넌트를 마운트할 때 자바스크립트로 <title> 태그의 값을 바꿔 주어야 함
// util.jsx
(...)
export const setPageTitle = (title) => {
const titleElement = document.getElementByTagName("title")[0];
titleElement.innerText = title;
};
// Home.jsx
import { setPageTitle } from "../util";
const Home = () => {
useEffect(() => {
setPageTitle("Roy의 감정 일기장");
}, []);
};
export default Home;
Favicon 설정하기
Favicon은 브라우저 탭에서 페이지 제목 왼쪽에 있는 작은 아이콘으로서, 사용하고자 하는 favicon.ico 파일을 public 폴더에 넣고 사용함
오픈 그래프 태그 설정하기
오픈 그래프 태그는 링크를 공유할 때, 썸네일, 페이지 제목, 간단한 설명 등도 함께 노출하도록 설정하는 태그
// index.html
<!DOCTYPE html>
<html>
<head>
<title>Roy의 감정 일기장</title>
<meta property="og:image" content="%PUBLIC_URL%/thumbnail.png" />
<meta property="og:title" content="감정 일기장" />
<meta property="og:description" content="나만의 감정 일기장" />
</head>
</html>
배포
vercel 사이트에서 가입
[vercel 로그인]
> vercel login
[ 빌드 ]
> npm run build
[ 배포 ]
> vercel
[ 빌드와 배포를 동시에 ]
> vercel --prod