본문 바로가기
Study Note/React

React #SPA 개발하기 #1. 절대 경로 설정, 라우팅

by 시뮝 2021. 3. 14.
728x90

SPA란?

SPA는 Single Page Application의 약어로 하나의 페이지 내에서 새로고침 없이 내용(page)을 교체하는 애플리케이션을 뜻한다. 실제 실무에서 자주 개발했던 방식이다.

 

리소스 정보를 페이지 이동이 빨라지는 장점이 있으나 초기에 모두 다운 받아야하므로 규모가 큰 애플리케이션인 경우 lazy loading이나 SSR를 활용하여 최적화해줘야한다.

 


React SPA 개발 준비

React로 SPA를 개발하기 위해 create-react-app으로 애플리캐이션을 추가해준 뒤 아래와 같이 진행한다.

  • yarn add react-router
  • yarn add react-router-dom
  • src/pages 경로에 Home.js와 About.js 페이지를 작성한다.
  • 컴포넌트들을 불러와 파일 하나로 내보낼 수 있도록 인덱스 파일을 생성한다.
// "src/pages/index.js"
export { default as Home } from './Home';
export { default as About } from './About';

 

SPA로 출력할 페이지 라우트를 설정해준다.

//"src/App.js"
import React from 'react';
import { Route } from 'react-router-dom';
import {
  Home,
  About
} from 'pages';

const App = () => {
  return (
    <div>
      <Route exact path="/" component={Home}/>
      <Route path="/about" component={About}/>
    </div>
  )
}

export default App;

 

주소 뒤에 /mypage가 붙었을 때 Home 페이지가 출력되도록 설정하고 싶다면 exact 부분을 빼면 된다. 완전히 일치하였을 때만 출력하고 싶다면 exact 부분을 작성한다. (나의 로컬 주소는 localhost:3000 이다.)

{/* localhost:3000일 때만 출력 */}
<Route exact path="/" component={Home}/>

{/* localhost:3000/ 뒤에 다른 주소가 있어도 출력 */}
<Route path="/" component={Home}/>

 

path 뒤에 물음표를 추가하여 Query String 정보를 파싱할 수 있다.

{/* 파라미터를 받는 첫 번째 방법 - exact로 구분하여 두줄 작성 */}
<Route exact path="/about" component={About}/>
<Route path="/about/:name" component={About}/>

{/* 파라미터를 받는 두 번째 방법 - 물음표를 추가하여 한줄로 작성 */}
<Route path="/about/:name?" component={About}/>
{/* 파라미터를 여러개 받는 방법 - /:를 여러개 작성 */}
<Route path="/about/:name/:age/:phone?" component={About}/>

 

절대경로 설정1 - NODE_PATH 에러발생

절대경로를 읽을 수 있도록 하기 위해 책(리액트를 다루는 기술)의 가이드에 따라 아래처럼 cross-env 설치하고 package.json의 "scripts" > "start", "build" 부분에 "cross-env NODE_PATH=src "를 추가하고 실행을 하였더니 절대경로를 읽어오지 못한다는 오류가 났다. 

{
  (...)
    "scripts": {
    "start": "cross-env NODE_PATH=src react-scripts start",
    "build": "cross-env NODE_PATH=src react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  (...)
}

 

이유를 찾아보니 NODE_PATH=src 는 더 이상 지원되지 않는다는 것이다. create-react-app 깃허브를 확인해보니 tsconfig.json 혹은 jsconfig.json의 baseUrl에 src를 설정하여 사용하라고 한다. 아직은 node_modules나 src만 지원 중이지만 가까운 미래에 추가로 다양한 별칭을 지원해준다고 하니 baseUrl을 사용해야겠다.

https://github.com/facebook/create-react-app/issues/5692

 

 

절대경로 설정2 - baseUrl 로 절대경로 설정하여 해결

잠깐 알고 가자면 tsconfig.json은 타입스크립트의 config 실행정보를 지정하는 파일이라 yarn add typescript이나 npm으로 인스톨하여 타입스크립트를 설치해주어야 정상적으로 빌드된다.

 

책 내용을 완독한 후 포트폴리오 사이트를 타입스크립트 기반 리액트로 구축할 것이기에 지금은 jsconfig.json으로 진행한다. 아래 코드를 package.json이 있는 동일 경로에 jsconfig.json으로 추가한다.  package.json에 수정했던 구문을 원복해주고 다시 빌드하면 App.js에 절대경로로 작성했던 'pages' 정보를 정상적으로 출력해주는 것을 확인할 수 있다.

{
    "compilerOptions": {
        "baseUrl": "src"
    },
    "include": [
        "src"
    ]
}

리액트 라우팅

NavLink 연결

react-router-dom의 NavLink를 활용하여 현재 URL에 따른 activeStyle을 적용할 수 있다.

component>Menu.js

import React from 'react';
import { NavLink } from 'react-router-dom';

const Menu = () => {
    const activeStyle = {
        color: 'green',
        fontSize: '2rem'
    };

    return (
        <div>
            <ul>
                <li><NavLink exact to="/" activeStyle={activeStyle}>홈</NavLink></li>
                <li><NavLink exact to="/about" activeStyle={activeStyle}>소개</NavLink></li>
                <li><NavLink to="/about/react" activeStyle={activeStyle}>React 소개</NavLink></li>
            </ul>
        </div>
    );
};

export default Menu;

src>App.js

import React from 'react';
import { Route } from 'react-router-dom';
import {
  Home,
  About
} from 'pages';
import Menu from 'components/Menu';

const App = () => {
  return (
    <div>
      <Menu/>
      <Route path="/" component={Home}/>
      <Route path="/about/:name?" component={About}/>
    </div>
  )
}

export default App;

 

자바스크립트 라우팅

js로 페이지를 이동해야 하는 경우 Link 컴포넌트는 단훈히 클릭했을 때 이동시키는 기능이므로 다른 방법을 사용해야 한다. 자바스크립트로 라우팅을 하려면 라우트로 사용된 컴포넌트가 받아 오는 props 중 하나인 history 객체의 push 함수를 활용한다.

src>App.js

import React from 'react';

const Home = ({history}) => {
    return (
        <div>
            <h2>홈</h2>
            <button onClick={() => {
                history.push('/about/javascript')
            }}>자바스크립트를 사용하여 이동</button>
        </div>
    );
};

export default Home;

 


 

 

 

 

728x90

댓글