최근 프로젝트를 진행하면서 로그인 기능을 구현하게 됐는데, 가장 먼저 막힌 부분이 로그인 후 화면 넘어가기 였다.
진행 중인 프로젝트는 모바일 관리자 웹앱으로 관리자 페이지라는 특성 답게 로그인을 하지 않는 다면 기능을 사용할 수 없어야 했다.
때문에 로그인 페이지가 없이 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 페이지로 이동한다.
'Develope > REACT' 카테고리의 다른 글
리액트 - API 기능을 이용한 리스트 검색 (0) | 2024.08.02 |
---|---|
리액트 API 리스트를 이용한 배열 값 검색 기능 (0) | 2024.08.02 |
React Vite CORS Error 해결 (0) | 2024.07.08 |
리액트 - 버튼으로 항목 추가 및 삭제 (0) | 2024.06.19 |
리액트 - 모달 만들기 (0) | 2024.06.18 |