[React] React SPA, React Router

jungmin Lee·2023년 8월 1일
0


React를 공부하면서 React Router 사용을 기본적으로 하게 되는데 프로젝트를 하면서 Outlet을 사용하는 방법 등 라우터의 기능을 다양하게 사용할 수 있는 부분들을 알게 되었다. React Router에 대해서 다시 한번 정리하는 시간을 가져보려고 한다.

React SPA

예전의 웹사이트들은 사용자가 웹사이트 내의 다른 페이지로 이동시, 페이지 전체를 매번 불러와야 했다. 웹사이트가 이전보다 복잡해지면서, 사용자와 서비스 사이에 많은 상호작용이 일어나게 되었고 중복되는 요소들을 매번 불러오는 것은 서버와의 불필요한 트래픽을 발생시켜 느린 반응성을 보여주면서 사용자 경험을 저하시키게 되었다. SPA는 Menu나 Footer 같은 중복되는 부분은 새로 불러오지 않고 업데이트가 필요한 부분만 새로 불러온다. 즉, 서버로부터 새로운 페이지를 불러오는 것이 아니라, 화면을 업데이트 하기 위해 필요한 데이터만 받아서 브라우저에서 해당하는 부분만 업데이트하는 방식으로 작동한다.

SPA 장점

  • 전체 페이지가 아니라 필요한 부분의 데이터만 받아서 화면에 업데이트 하므로 사용자의 상호작용에 빠르게 반응한다.
  • 서버에서는 요청 받은 데이터만 넘겨주므로 서버 과부화 문제가 줄어든다.
  • 화면 전체를 새로 렌더링 할 필요가 없으므로 사용자 경험을 향상시킨다

SPA 단점

  • JavaScript 파일의 크기가 크고 첫 화면 로딩 시 읽어들인 HTML파일은 거의 비어있다.
    JavaScript 파일을 기다리는 시간이 걸리게 되므로 첫 화면 로딩시간이 길어진다.
  • 검색 엔진 최적화(SEO)는 HTML 파일에 있는 자료를 분석하는 방식으로 구동하는데 SPA의 경우 HTML 파일에 많은 자료가 없으므로 검색 엔진이 적절하게 동작하지 못한다

React Router

React Router를 사용하여 다른 주소에 따라 다른 뷰를 보여줄 수 있다.

React Router 설치

아래와 같이 입력하면 설치할 수 있으며 package.json파일의 dependencies 항목에서 설치된 것을 확인할 수 있다.

npm install react-router-dom

React Router 사용법

App.js
BrowserRouter, Routes, Route를 react-router-dom을 설치하여 세팅한다. 그리고 라우팅을 하기 위한 컴포넌트들도 세팅한다.

  • BrowserRouter
    TML5의 History API를 사용해 페이지를 새로고침하지 않고도 주소를 변경할 수 있게 해주며 상위에 작성되어야 한다. BrowserRouter는 ReactDOM의 렌더 단계인 index.js 파일에 작성하여도 된다.
  • Routes
    경로를 매칭해주는 역활로 Route 컴포넌트를 감사써 경로가 일치하는 단 하나의 라우터만 렌더링을 시켜주는 역활을 한다.
  • Route
    path 속성을 지정하여 해당 path에서 어떤 컴포넌트를 보여줄지 정하며 Link 컴포넌트가 정해주는 URL경로와 일치하는 경우에만 작동된다.
  • 사용자가 지정한 주소이외의 주소로 접근하게 되면 의도한 화면이 보이지 않을 수 있다. 이런 경우에는 path=”*” 속성을 적용하면 지정되지 않은 주소로 접근할 시에는 이 속성이 설정되어 있는 컴포넌트를 보여주게 된다
import { BrowserRouter, Routes, Route} from 'react-router-dom" 
import Header from './components/Header';
import Home from './pages/Home';
import MyPage from './pages/MyPage';
import Posts from './pages/Posts';

export default function App() {
  return (
    <BrowserRouter>
      <Header />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/mypage" element={<MyPage />} />
        <Route path="/posts" element={<Posts />} />
      </Routes>
    </BrowserRouter>
  );
}

Header.jsx

  • Link
    Link는 경로를 연결해주는 역활을 하는 컴포넌트로 ReactDOM으로 렌더링하면 Link컴포넌트는 a요소로 바뀌는 것을 알 수 있다.
    to 속성으로 Route 컴포넌트에 설정해 준 Path 주소를 연결해준다.
  • NavLink
    Link 대신에 NavLink를 사용할 수도 있다. NavLink는 현재 URL과 정확히 일치하는 경우에 스타일을 적용하여 활성화된 상태를 표시해줄 수 있다. 'activeClassName', 'activeStyle', 'isActive'와 같은 prop을 통해 적용하고 싶은 스타일링을 적용할 수 도 있다.
import { Link } from 'react-router-dom';

export default function Header() {
  return (
    <Nav>
      <Link to="/">
        Home
      </Link>
      <Link to="/posts">
        Posts
      </Link>
      <Link to="/mypage">
        MyPage
      </Link>
    </Nav>
  );
}

useNavigate는 특정 행동을 했을 때 해당 주소로 이동시켜주는 역할을 하며 Link와는 달리 함수 호출을 통해 특정 조건에 따라 페이지를 이동할 수 있다.

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

function Mypage() {
  let navigate = useNavigate();

  function handleClick() {
		if(로그인 한 상태) {
			navigate('/mypage');
		} else {
			navigate('/login');	
		}
  }

  return <button onClick={handleClick}>마이페이지</button>;
}

createBrowserRouter, RouterProvider, Outlet

react-router-dom을 위에서 적용시켜준 방법과 다르게 작성할 수 있는 방법이 있다. Outlet을 사용하면 하위 경로가 렌더링될 때 중첩된 UI가 표시될 수 있다.
index.js 파일이나 App.js파일에서 createBrowserRouter로 router에 대한 내용들을 정의한다. RouterProvider로 router를 전달해준 다음에 App.js파일에서 Outlet으로 children 컴포넌트들이 보여지게 설정하였다.
index.js

import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import "./index.css";
import App from "./App";
import NotFound from "./pages/NotFound";
import Home from "./pages/Home";
import MyPage from "./pages/MyPage";
import Posts from "./pages/Posts";

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
    errorElement: <NotFound />,
    children: [
      { index: true, path: "/", element: <Home /> },
      { path: "/mypage", element: <MyPage /> },
      { path: "/posts", element: <Posts /> },
    ],
  },
]);

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

App.js

import { Outlet } from "react-router-dom";
import Header from "./components/Header";

function App() {
  return (
    <>
      <Header />
      <Outlet />
    </>
  );
}

export default App;

react-router-dom은 팀원들과 하는 프로젝트나 개인으로 하는 작은 프로젝트에서도 사용하지 않은 적이 없을만큼 거의 사용했던 거 같아서 한번 더 정리하는 시간을 가져봤다. React를 처음 배울때는 급하게 여러가지를 배워서 정신이 없었는데 시간적인 여유를 가지고 한번씩 정리해보니 내용이 기억에 잘 남을 거 같다

profile
Leejungmin

0개의 댓글