티스토리 뷰

개발공부/🟦 React.js

[React] SPA와 라우팅

2022. 8. 13. 12:57
 

React – A JavaScript library for building user interfaces

A JavaScript library for building user interfaces

reactjs.org

 

 

 SPA 

 

 

▶  Single Page Application (SPA)

 

:  SPA(Single Page Application)은 하나의 페이지 요청으로 전체 웹앱을 사용하는 방식

 

Client-side routing 기술을 활용  →  페이지 진입 시 리로드없이 라우팅한다.

AJAX 기술을 활용  →  페이지 이동 시 서버에 데이터만 요청하여 자바스크립트로 페이지를 만든다.

 

-  유저가 웹페이지를 사용하며 모바일 앱 같은 경험을 느낄 수 있다.

-  자바스크립트만을 활용해 전체 페이지를 만들기에 첫 요청 시 빈 페이지를 받게 된다.

-  MPA와 다르게 여러 페이지를 하나의 앱의 구성요소로 보고 여러 페이지 간의 스타일, 컴포넌트를 재활용하는 방향으로 구현 가능하다.

 

 

 

* Multi Page Application

:  MPA(Multi Page Application)은 서버에 미리 여러 페이지를 두고, 유저가 네비게이션 시 요청에 적합한 페이지를 전달하는 방식

 

-  미리 서버에서 전체 페이지를 빌드해 브라우저로 전송한다.

-  서버에 라우팅을 처리하는 기능이 있고, 서버에서 여러 페이지를 관리한다.

-  페이지 요청마다 모든 리소스를 다시 받아오므로 페이지 간 데이터를 재활용하기 힘들다.

 

 

 

 

 

▶  SPA의 장단점

 

장점

-  서버에서 페이지를 만들 필요가 없으므로 CDN에 캐싱이 가능하다.

-  매번 페이지 요청을 할 필요가 없어 네트워크 요청이 줄어든다.

-  마찬가지로 데이터 요청 등을 캐싱하여 재사용하는 등 제약 조건이 줄어든다.

-  웹사이트를 개별 페이지보다는 하나의 앱으로 보는 설계로 고도의 소프트웨어 설계와 패턴을 적용할 수 있다.

 

 

단점

-  MPA방식 보다는 Search Engine Optimization(SEO)에 불리하다.

-  하나의 자바스크립트 앱이 지속하므로, 메모리 관리와 성능, 데이터 활용 등이 중요하다.

-  여러 페이지를 전송받는 것 보다 하나의 거대한 자바스크립트 앱을 전송받아야 하므로 코드가 많아질수록 로드 속도가 느려진다.

 

 

 

 

 

▶  SPA에서의 라우팅

 

-  주로 History API 혹은 URL Hash를 이용해 페이지 리로드 없는 페이지 전환을 구현한다. (history, location 등 HTML5 API를 활용)

-  visibilitychange, popstate, beforeunload 등 window event를 활용하여 페이지 전환 등의 이벤트 시 핸들러를 등록하여 특정 동작을 하이재킹한다.

-  react-router, reach-router 등의 라이브러리를 활용하면 라우팅 관련 기능을 쉽게 사용할 수 있다.

 

 

 

 

 

 

 

 React-Router 

 

 

▶  react-router 란?

 

Declarative routing for React

 

-  React의 JSX를 이용하거나 History API를 사용하여 라우팅을 구현한다.

-  웹에서는 react-router-dom을 사용한다.

-  적용 시, 서버의 모든 path에서 같은 앱을 서빙하도록 해야 한다.

 

 

 

 

▶  react-router의 기능

 

-  React 컴포넌트를 특정 path와 연결하면 해당하는 path로 진입 시 컴포넌트를 렌더링하게 한다.

-  query, path variable 등 URL parameter를 얻어 활용할 수 있다.

-  조건에 맞지 않을 경우 redirect 할 수 있다.

-  페이지 이동 시 이벤트 핸들러를 등록할 수 있다.

-  "/posts/my-post-1" 등의 nested route를 구현할 수 있다.

 

 

 

 

▶  react-router의 사용

import { BrowserRouter, Route, Switch } from 'react-router-dom';

export function App() {
    return (
        <BrowserRouter>
            <Switch>
                <Route path="/about"><AboutPage /></Route>
                <Route path="/contact"><ContactPage /></Route>
                <Route path="/"><HomePage /></Route>
            </Switch>
        </BrowserRouter>
    )
}

 

 

-  <BrowserRouter>로 감싸 Router Context를 제공해야 한다.

-  Route로 path를 정의하고 그 안에 렌더링하고자 하는 컴포넌트를 넣는다.

-  Link로 특정 페이지로 이동 시 리로드 없이 페이지가 이동한다.

-  Switch로 매칭되는 라우트 하나를 렌더링하게 할 수 있다. (Switch 를 안쓰면 매칭되는 라우터를 전부 렌더링함)

 

 

 

 

 

 

▶  react-router 컴포넌트

 

 

1)  BrowserRouter

 

:  HTML5의 History API를 사용하여 UI와 URL의 싱크를 맞추는 역할

 

-  모든 URL에 대해 동작하게 하기 위해서는 서버 설정 필요하다.

-  모든 path 앞의 basename을 지정할 수 있다. ( ex. basename="/ko" )

-  forceRefresh로, 페이지 이동 시 리프레시할 것인지 지정할 수 있다.

 

 

 

 

2)  Switch

 

:  여러 Route 중 매치되는 Route 위에서부터 하나 선택하여 렌더링

 

-  매칭되는 Route가 없으면 아무것도 보여주지 않는다.

-  fallback용으로 404 Not Found Page를 추가할 수 있다.

-  path="/"의 경우 모든 path에 매칭되므로 exact 키워드를 추가하거나 가장 아래로 내려야 정상적으로 작동한다.

 

 

 

 

3) Route

 

:  path와 컴포넌트를 매칭

 

-  매칭되는 컴포넌트는 children으로 넣어주거나 component prop으로 넘기는 방법이 있다.

-  exact 키워드로 정확하게 매칭하는 path를 설정한다.

-  Route로 렌더링 되는 최상위 컴포넌트는 match, location, history를 prop으로 받는다.

-  render prop으로 매칭되었을 때 실제 어떤 컴포넌트를 렌더링할지 통제할 수 있다.

 

 

 

 

4)  Redirect

 

:  Link와 비슷하나 렌더링되면 to prop으로 지정한 path로 이동

 

-  Switch 안에서 쓰일 경우 from, to를 받아 이동할 수 있다. ( ex. from="/" to="/login" )

 

 

 

 

5)  Link, NavLink

 

:  to prop을 특정 URL로 받아 클릭 시 네비게이션

 

-  anchor tag를 래핑한다.

-  NavLink의 경우 매칭 시 어떤 스타일을 가질지 등의 추가 기능이 있다.

-  to에 location object나 함수를 받을 수 있다.

 

 

 

 

6)  useHistory, useLocation, useParams, useRouteMatch

 

-  최상위 컴포넌트가 아니더라도 hook으로 react-router 관련 객체에 접근할 수 있다.

-  history, location, params, match 객체에 접근한다.

 

 

 

 

 

 

▶  react-router 로 페이지 구성하기

 

 

1)  공통 페이지 레이아웃

 

PageLayout.jsx

export default function PageLayout({ header, children }) {
    return (
        <Layout>
            <Navigation />
            <header>
            	<h2>{header}</h2>
            </header>
            <main>{children}</main>
        </Layout>
    );
}
const Layout = styled.div`
    height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
`;

 

 

 

2)  공통 페이지 네비게이션

 

Navigation.jsx

function Navigation() {
    return (
        <Nav>
            <NavLink to="/">Home</NavLink>
            <NavLink to="/about">About</NavLink>
            <NavLink to="/contact">Contact</NavLink>
        </Nav>
    );
}
const Nav = styled.div`
    padding: 24px;
    
    & > a:not(:first-of-type) {
    	margin-left: 24px;
    }
`;

 

 

 

3)  개별 페이지 컴포넌트

 

HomPage.jsx

function HomePage() {
    return (
   	 <PageLayout header="Home Page">홈페이지에 오신 것을 환영합니다.</PageLayout>
    );
}

 

 

 

4) 라우터 연결

 

App.js

function App() {
    return (
        <BrowserRouter>
            <Switch>
                <Route exact path="/"><HomePage /></Route>
                <Route path="/about"><AboutPage /></Route>
                <Route path="/contact"><ContactPage /></Route>
            </Switch>
        </BrowserRouter>
    );
}

 

 

 

 

 

 

▶  react-router 응용

 

 

응용 1)  Private Route 만들기

 

-  특정 조건이 충족되지 않았을 때 다른 페이지로 Redirect 하도록 하는 기능

-  유저의 상세 페이지, 개인정보 변경 페이지 등을 만들 때 사용된다.

 

declarative (선언적인 방법)

function PrivateRoute({ component: Component, ...props }) {
    return <Route {...props} render={props => {
        const isLoggedIn = !!getUserInfo();
        
        if (!isLoggedIn) {
        	return <Redirect to="/login" />
        }
        
        return <Component {...props} />
    }}
}

 

imperative (명령형)

function usePrivateRoute(validateFunc) {
    const history = useHistory();
    
    useEffect(() => {
        if (!validateFunc()) {
        	history.push("/login")
    	}
    }, []);
}

 

 

 

 

응용 2)  query string 활용하기

 

-  URL의 query string 정보를 활용해 앱을 구성할 수 있다.

-  URLSearchParams API를 활용하여 좀 더 간편하게 query string을 조작할 수 있다.

function ContactPage() {
    const location = useLocation();
    const searchParams = new URLSearchParams(location.search);
    const email = searchParams.get("email");
    const address = searchParams.get("address");
    
    return (
        <PageLayout header="Contact Page">
            <em>{email}</em>
            <br />
            <strong>{address}</strong>
        </PageLayout>
    );
}
function App() {
    // ...
    return (
        <Link to="/contact?email=example@example.com&address=Seoul">
        	Contact
        </Link>
    );
}

 

 

 

 

 


 이 글은 엘리스의 AI트랙 5기 강의를 들으며 정리한 내용입니다.

반응형

'개발공부 > 🟦 React.js' 카테고리의 다른 글

[React] POSTMAN, OpenAPI, CORS  (0) 2022.08.16
[React] 비동기 통신과 Promise  (0) 2022.08.16
[React] React 스타일링  (0) 2022.08.12
[React] Todo-List 만들기  (0) 2022.08.12
[React] Hooks  (0) 2022.08.11
프로필사진
개발자 삐롱히

프론트엔드 개발자 삐롱히의 개발 & 공부 기록 블로그