UMC 8th Web 워크북

🍎 로그인/회원가입 페이지 구현을 위한 복습

minnote29 2025. 4. 13. 16:21

🍎 새 프로젝트 생성

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 공식문서 가서 확인하면 된다. 

 

그럼, 어떤 페이지를 만들 것이냐

  1. 홈페이지
  2. 로그인 페이지
  3. 회원가입 페이지

그럼 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;