🍎 새 프로젝트 생성
umc 강의를 참고해서 정리를 했다.
일단, 로그인/회원가입 페이지를 만들기 위해서 폴더를 이동해주고,
$ pnpm create vite
를 해서 새 프로젝트를 생성해줬다.
그 다음,
$ cd UMC-8th-mission-FE
$ pnpm i
해서 pnpm 다운로드를 해준다. 비주얼 스튜디오를 활용하고 있기 때문에,
$ code .
해서 해당 프로젝트로 이동을 해준다.
이렇게 실행을 완료하면 페이지가 필요하니까
$ pnpm i react-router-dom
깔아주고, tailwind css 활용을 위해서 다운로드 해준다.
$ pnpm install tailwindcss @tailwindcss/vite
src의 vite.config.ts가서
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import tailwindcss from '@tailwindcss/vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), tailwindcss()],
})
이렇게 수정을 하고,
index.css에
@import "tailwindcss";
이 코드를 넣어주면 된다. index.css 안의 내용 지워주고, App.css도 내용 전부 지워주기.
그 다음, 완전 페이지 재구성을 위해 App.tsx 내부를 다 지워준다.
🍎 페이지 구현하기
일단 App.tsx에서 tailwind css가 잘 작동하는지 테스트해본다.
import './App.css'
function App() {
return (
<h1 className={'text-2xl'}>
민
</h1>
)
}
export default App;
이런 식으로 하면, 페이지가 잘 뜨는 것을 알 수 있다.
스타일링 관련해서 모르는 것은 tailwind css 공식문서 가서 확인하면 된다.
그럼, 어떤 페이지를 만들 것이냐
- 홈페이지
- 로그인 페이지
- 회원가입 페이지
그럼 pages 폴더 만들고, HomePage, NotFoundPage를 만들어준다. 그 다음, 아래처럼 코드를 작성해주고,
import './App.css'
import { createBrowserRouter, RouterProvider } from "react-router-dom"
import HomePage from './pages/HomePage';
import NotFoundPage from './pages/NotFoundPage';
const router = createBrowserRouter([
{
path: '/',
element: <HomePage />,
errorElement: <NotFoundPage />
},
])
function App() {
return (
<RouterProvider router={router} />
)
}
export default App;
App.tsx 내부에 다른 요소들을 넣어서 관리하기 위해서 outlet을 만들어준다.
{
path: '/',
element: <HomePage />,
errorElement: <NotFoundPage />,
children: [
{path: 'login', element: <Loginpage /> }
],
},
이런 식으로 하면, 아마 HomePage 내용이 뜰 것이다. 여기서 놓칠 수 있는 부분이 있는데 element 같은 경우는 보통 공유되는 구성요소들이 들어가야 한다. 쿠팡을 예시로 들어보자. 아래 코드 같은 경우, <div className="h-dvh"> 라는 것을 해줌으로써 페이지 전체를 차지하게 될 것이다. 쿠팡처럼 각각의 요소들이 원하는 위치에 올 수 있도록 flex 속성을 써줘야 한다.
const HomePage = () => {
return (
<div className="h-dvh">
<nav> 네비게이션 바 입니다.
</nav>
<main>홈페이지</main>
<footer>푸터</footer>
</div>
)
}
export default HomePage;
세로축 정렬로 되게 해주고, main 부분을 flex 1만큼 주면 푸터가 이제 맨 아래로 내려가게 되고 내비게이션은 내비게이션 크기만큼, 푸터는 푸터 크기만큼만 차지하고 홈페이지는 나머지 부분 전부를 다 차지하게 되는 것을 확인할 수 있다.
하지만, 지금 구현해야 되는 화면은 로그인 페이지인데 홈페이지가 뜨고 있다. 그 이유가 뭐냐면 메인에 홈페이지가 들어갈 게 아니라 여기가 이제 children 들이 outlet이 나와야 한다. 그렇게 하면 이제 로그인에 해당하는 경로가 나오게 될 것이다.
import { Outlet } from "react-router-dom";
const HomePage = () => {
return (
<div className="h-dvh flex flex-col">
<nav> 네비게이션 바 입니다.
</nav>
<main className='flex-1'>
<Outlet />
</main>
<footer>푸터</footer>
</div>
)
}
export default HomePage;
이 Outlet이 뭐냐면 App.tsx 들어가보면, element에서는 보통 공유하는 레이아웃을 적어주는 게 일반적이다. 여기서 공유하는 레이아웃이 뭐냐면 넷바랑 푸터 같은 경우는 고정적이고 이 안에 가운데 요소 즉 아울렛만 바뀌게 되는 것이다. 그래서 홈 경로일 때는 홈이 보이는 것이다.
지금 홈 경로일 때 아무것도 안 보여지는 것은 이 아울렛에 children들이 렌더링 되는 것이다. 근데 우리가 / 라는 것을 안 정해줬다. 아울렛 부분에 홈 경로일 때는 아무것도 보여 줄게 없는 것이다. 그렇기 때문에 홈 경로를 만들어주면 된다.
{
path: '/',
element: <HomePage />,
errorElement: <NotFoundPage />,
children: [
{index: true, element: <div>Home</div>},
{path: 'login', element: <Loginpage /> }
],
},
이렇게 하면 홈 경로일 때, {index: true, element: <div>Home</div>}, 이 코드가 렌더링 된다고 보면 된다.
사실상 홈 경로일 때는 페이지라는 개념보다는 레이아웃의 개념이 맞을 것이다. 그래서 layout 폴더를 하나 만들고, HomeLayout.tsx를 만들어준다.
import { Outlet } from "react-router-dom";
const HomeLayout = () => {
return (
<div className="h-dvh flex flex-col">
<nav> 네비게이션 바 입니다.
</nav>
<main className='flex-1'>
<Outlet />
</main>
<footer>푸터</footer>
</div>
)
}
export default HomeLayout;
import './App.css'
import { createBrowserRouter, RouterProvider } from "react-router-dom"
import NotFoundPage from './pages/NotFoundPage';
import Loginpage from './pages/Loginpage';
import HomeLayout from './layouts/HomeLayout';
import HomePage from './pages/HomePage';
const router = createBrowserRouter([
{
path: '/',
element: <HomeLayout />,
errorElement: <NotFoundPage />,
children: [
{index: true, element: <HomePage />},
{path: 'login', element: <Loginpage /> }
],
},
])
function App() {
return (
<RouterProvider router={router} />
)
}
export default App;
이렇게 하면 이제 홈페이지일 때는 홈페이지만 보이고, 로그인할 때는 로그인 페이지가 잘 보일 것이다.
회원가입 페이지도 필요하므로 이 페이지도 만들어준다. 이렇게 하면 signupPage도 정상적으로 뜰 것이다.
const SignupPage = () => {
return (
<div>SignupPage</div>
)
}
export default SignupPage
import './App.css'
import { createBrowserRouter, RouterProvider } from "react-router-dom"
import NotFoundPage from './pages/NotFoundPage';
import Loginpage from './pages/Loginpage';
import HomeLayout from './layouts/HomeLayout';
import HomePage from './pages/HomePage';
import SignupPage from './pages/SignupPage';
const router = createBrowserRouter([
{
path: '/',
element: <HomeLayout />,
errorElement: <NotFoundPage />,
children: [
{index: true, element: <HomePage />},
{path: 'login', element: <Loginpage /> },
{path: 'signup', element: <SignupPage /> }
],
},
])
function App() {
return (
<RouterProvider router={router} />
)
}
export default App;
'UMC 8th Web 워크북' 카테고리의 다른 글
🍎 회원가입 관리 (0) | 2025.04.13 |
---|---|
🍎 로그인 구현해보기 (umc 4주차) (0) | 2025.04.13 |
🍎 서버 환경 관련 Ot & Swagger 간단 활용 (umc 정리) (0) | 2025.04.13 |
🍎 Custom-hook (4주차 UMC 강의 정리 + @) (0) | 2025.04.12 |
🍿 TMDB 영화 상세 페이지 불러오기 (Umc 3주차 미션3) (0) | 2025.04.07 |