본문 바로가기
Develope/REACT

React - 로그인 페이지 구현을 위한 route 경로 설정

by ccuccu 2024. 7. 31.

최근 프로젝트를 진행하면서 로그인 기능을 구현하게 됐는데, 가장 먼저 막힌 부분이 로그인 후 화면 넘어가기 였다.

진행 중인 프로젝트는 모바일 관리자 웹앱으로 관리자 페이지라는 특성 답게 로그인을 하지 않는 다면 기능을 사용할 수 없어야 했다.

때문에 로그인 페이지가 없이 App.jsx에서 바로 라우팅 하여 넘어가던 페이지들과 달리, 로그인을 먼저 한 후 다른 페이지로 넘어가야 하는 기능 구현이 필요했다.

 

코드 구현하기

웹은 html을 읽어 표시되며, 보통 react의 html은 한개이므로 웹은 index.html의 파일을 읽어 화면에 표시되는 것을 알 수 있다.

해당 파일은 아래와 같이 쓰여있다.

<!doctype html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>BueaLine</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

 

id값이 root인 div 화면을 불러오는 것을 알 수 있다.

 

이제 main.jsx 파일을 살펴보면 

ReactDOM.createRoot(document.getElementById('root')).render(
  <App />
);

 

위와 같이 쓰여있는데, 보면 ReactDom에 id가 root인 dom 요소를 가져오고, createRoot로 프로젝트의 루트를 생성한다.

그 다음 render를 통해 App.jsx를 호출한다.

App을 호출 할 때 router의 힘을 빌려 호출하면, 내가 원하는 로그인 기능을 구현할 수 있다.

 

프로젝트는 관리자 전용 사이트기 때문에, 로그인이 되지 않으면 안의 기능을 사용할 수 없으므로 가장 큰 경로는 두 가지이다.

1. 로그인 페이지

2. 관리자 페이지

 

먼저 1번 로그인 페이지에서 인증하고, 권한이 부여 되어야만 2번 관리자 페이지를 사용할 수 있다.

그렇기 때문에 바로 root로 App을 호출하는 현재 방법으로는 기능을 구현하기 어려워 router를 이용하여 페이지를 나눠주고자 한다.

 

Router란?

리액트에서 사용 할 수 있는 라이브러리로 경로 설정 시 해당 페이지로 이동한다.

npm i react-router-dom

위의 코드를 터미널에 작성하면 react-router-dom 이라는 라이브러리가 프로젝트에 설치되고 사용할 수 있다.

그런 다음 main.jsx 파일에 아래와 같은 코드를 삽입하면 된다.

 

import { route } from 'react-router-dom'

<Route path = '/' element = {<App />} />

 

route를 사용하기 위해서는 파일 상단에 route를 선언하여 사용해야한다.

그 다음 아래처럼 Route 태그를 사용하여 내가 원하는 경로를 선정해준다.

path는 url 경로로 위의 주소창에 /로 구분되어 표시되며, /는 리액트 실행 시 가장 기본 경로로 선정된다.

element는 내가 호출 할 컴포넌트(jsx 파일)를 뜻한다.

 

하지만 위의 코드처럼 진행하면 위와 동일하게 app만 호출하게 된다. 그렇다면 어떻게 해야 페이지를 구분하여 사용할 수 있을까?

import { BrowserRouter, Routes, Route } from "react-router-dom";

<BrowserRouter>
    <Routes>
      <Route path='/' element={<Login />} /> {/* 로그인 페이지 라우팅*/}
      <Route path='/app' element={<App />}> {/* 버튼 클릭 후 라우팅 */}
        {/* 앞으로 app 내부에 구현 될 라우트 컴포넌트들 */}
      </Route>
    </Routes>
  </BrowserRouter>

 

route를 여러개 사용하면 Routes라는 태그로 한번 묶어줘야 한다.

 

BrowserRouter는 페이지 이동 없이 url을 업데이트 해주며 최상위 라우팅 경로를 선정해준다.

 

그렇기 때문에 위처럼 구현하면 주소창에 웹페이지 이동 시 기본 경로인 로그인 페이지로만 이동되며 로그인 페이지의 로그인 버튼을 클릭 시에 /app 경로로 이동 시켜주면 된다.

import { useNavigate } from 'react-router-dom'

const navigate = useNavigate();
const handleLogin = () => {
	navigate('/app')
}

<button type='button' className='btn' onClick={loginInfo}>Login</button>

 

Navigate라는 기능을 이용할건데, 기존 route가 spa 방식으로 하단의 App 부분만 렌더링 하여 보여주는 방식과 다르게,

navigate로 경로를 설정하여 이동 시에는 새로운 페이지로 화면이 이동한다.

따라서 기본 경로인 로그인에서 벗어나서 /app으로 이동하게 된다.

 

하지만 이렇게 하면 /app 내부에서는 페이지 이동이 불가능기 때문에 App.jsx에 추가 수정이 필요하다.

import { Outlet } from 'react-router-dom'

<div className= "App">
	<Outlet />
</div>

 

바로 Outlet을 이용하여 main.jsx에 이미 route로 호출된 경로를 중복으로 호출하여 동적으로 라우팅 되게 설정해줘야 한다.

 

정리하기

1. main.jsx 파일에 경로를 선정해준다.

import ReactDOM from 'react-dom/client';
import { BrowserRouter, Routes, Route } from "react-router-dom"; // react-router-dom 호출
import Login from "./pages/Login.jsx"; // 로그인 페이지
import App from './App.jsx'; // 로그인 후 컨텐츠를 호출 할 페이지
import Contact from './pages/Contact'; // 컨텐츠1
import TotalChart from './pages/TotalChart'; //컨텐츠2
import Category from './pages/Category'; // 컨텐츠3

ReactDOM.createRoot(document.getElementById('root')).render(
  <BrowserRouter>
    <Routes>
      <Route path='/' element={<Login />} /> {/* 로그인 페이지 라우팅*/}
      <Route path='/app' element={<App />}> {/* 버튼 클릭 후 라우팅 */}
        <Route path='contact' element={<Contact />} />
        <Route path='totalchart' element={<TotalChart />} />
        <Route path='category' element={<Category />} />
        <Route index element={<Category />} /> {/* 기본 경로 */}
      </Route>
      {/* <Route path="*" /> */} {/* notFound 페이지 */}
    </Routes>
  </BrowserRouter>
);

 

2. App.jsx 파일에 로그인 후 보여질 컨텐츠 들을 다시 선언한다.

import { Outlet } from 'react-router-dom';

function App() {
	<div className = "App">
    	<Outlet />
    </div>
}

Outlet으로 표시하지 않고 다시 경로를 설정한다면 중복으로 선언 되어 오류가 난다.

 

3. 로그인 페이지에 App.jsx로 이동 기능을 구현한다.

import { useNavigate } from 'react-router-dom';

const Login = () => {
	// 로그인 버튼 클릭 시 화면 이동
    const navigate = useNavigate();
    const handleLogin = () => {
        navigate('/app'); // 로그인 후 기본 경로
    };
	return (
    	<div className = "Login">
            <input type="text" />
            <input type="password" />
            <button onClick={login}>Login</button>
        </div>
    )
}

export default Login;

위처럼 코드를 작성하면 로그인 버튼 클릭 시 navigate 경로를 따라 /app 페이지로 이동한다.