SPA에 라우팅으로 페이지 바꾸기 [TOY / Simple-SNS]

알락·2022년 11월 20일
0

Simple-SNS

목록 보기
4/9

배경

웹서비스에서 여러 기능을 제공하다보면 한 화면에 모든 것을 제공하기 힘들 때도 있다. 그리고 사용자에게도 비좁은 화면에서 꾸역꾸역 기능을 제공하기보다는 넓은 화면에서 새롭게 기능을 제공하는 것이 더 편하게 느껴질 수 있다.
지금 진행하고 있는 프로젝트도 우선 필요에 의해 페이지를 나눠서 제공해보기로 했다.

기술

우선 SPA를 알고 있는 사람들에게는 페이지를 새로 제공한다는 것이 의아할 것이다. 왜냐하면 SPA는 말그대로 페이지 하나로 서비스를 제공하는 것을 말하기 때문이다. 새로운 페이지 요청을 줄이거나 없애기 위하여 SPA를 사용하였는데, 이렇게하면 React로 구현하는 의미가 없다고 생각될 수 있다.
하지만 기존의 새로운 페이지 요청은 그에 필요한 모든 파일, 이를테면 HTML, CSS, 그리고 JavaScript까지 모두 재요청하여 사용한다는 것이다. 물론 이도 캐시를 이용한다면 매번 새로 읽어들이는 속도가 개선이 될 것이다.

하지만 이번에 사용하는 라이브러리도 react에서 제공하는 react-router를 이용한다는 것을 생각해보자. Client Side Rendering이다. 제공되어 있는 React 기반 컴포넌트들은 그대로 있는 채 새롭게 렌더링 되는 부분에 필요한 데이터만 요청하여 클라이언트의 화면에 보이게 한다.

이를 프로젝트에 적용해보았다.

구현

[디렉터리 구조]

+-- src
	+-- component
		+-- Dropdown.js
		+-- Message.js
		+-- Navbar.js
		+-- Send.js
	+-- page
		+-- Login.js
		+-- Mypage.js
		+-- Plaza.js
+-- App.js
+-- index.js

고민을 하다가 페이징 기능을 추가하면서 이전과는 다른 디렉터리 구조를 만들기로 하여 여기에 소개한다. 이런 디렉터리 구조를 같게 된 이유는 앞으로 프론트엔드 개발은 기능을 위주로 하는 페이지 단위 개발과, 페이지에 들어가는 요소 위주의 컴포넌트 개발로 나뉘어질 것 같았기 때문이다.

[React router 설치]

> npm install react-router-dom

[index.js -> BrowserRouter 추가]

// 생략
import {BrowserRouter} from 'react-router-dom';
// 생략

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

위는 리액트로 제공되는 웹서비스가 URL 기반의 라우팅을 제공한다는 일종의 선언이다.

[Navbar.js -> Link 추가]

import {Link} from "react-router-dom";
import "./Navbar.css";

const Navbar = ()=>{
    return (
        <nav>
            <div className="nav-group">
                <div className="logo-wrapper">
                    <button className="btn-logo">ZET</button>
                </div>
                <Link className="btn-nav" to="/">
                    <svg></svg>
                    <h2>Home</h2>
                </Link>
                <Link className="btn-nav" to="/mypage">
                    <svg></svg>
                    <h2>Mypage</h2>
                </Link>
                <Link className="btn-nav" to="/login">
                    <svg></svg>
                    <h2>Login</h2>
                </Link>
            </div>
            <div className="copyright">
                <div className="copyright-line"></div>
                <p>©JejuAlrock</p>
            </div>
        </nav>
    )
}

export default Navbar;

기존 웹서비스에서 <a> 태그 역할을 하는 Link 컴포넌트를 네비게이션 바에 추가해준다. href 프로퍼티는 to가 대신하게 된다.

[App.js -> Routes, Route 추가]

// Components
import Navbar from "./component/Navbar.js";

// Pages
import Plaza from "./page/Plaza";
import Login from "./page/Login";
import Mypage from "./page/Mypage";

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

function App() {
  
  // 생략
  
  return (
    <div className="App">
      <Navbar></Navbar>
      <Routes>
        <Route path="/" element={<Plaza data={data} sendMessage={sendMessage} removeMessage={removeMessage} updateMessage={updateMessage}></Plaza>}></Route>
        <Route path="/mypage" element={<Mypage data={data} sendMessage={sendMessage} removeMessage={removeMessage} updateMessage={updateMessage}></Mypage>}></Route>
        <Route path="/login" element={<Login></Login>}></Route>
      </Routes>
    </div>
  );
}

export default App;

리액트 어플리케이션에서 URL을 이용한 Routing으로 바뀌는 부분을 Routes로 그룹화한다.
그리고 각각의 페이지에 해당하는 URL을 Route의 path로 지정해줄 수 있다. 이는 위의 Navbar 컴포넌트의 Link에서 지정해준대로 맵핑된다고 생각하면 된다. 그리고 지정된 URL로 요청이 들어오면 Route의 element 속성에서 지정해준 요소나 컴포넌트를 반환한다.

개선할 점

  • 리액트의 라우팅이 어떤 원리로 구현되는지 알아볼 필요가 있다. 화면에서 없어지는 부분은 아예 Unmount되는 건지 아니면 메모리에 남아있는 채로 존재하는지 등의 성능의 영향을 미치는 부분이 있는 지 알아봐야겠다.
profile
블록체인 개발 공부 중입니다, 프로그래밍 공부합시다!

0개의 댓글