2019. 9. 3. 13:37

1. previous page VS SPA

- previous page

: 유저가 요청할 때마다 페이지를 새로고침하며, 페이지를 로딩할 때마다 서버에서 리소를 전달받아 해석한 후 렌더링. HTML파일 또는 템플릿 엔진(ex: pug)등을 사용해서 뷰를 어떻게 보일지도 서버에서 담당

=> 단점 : 서버에서 렌더링을 담당하므로 그만큼 서버자원 소모->불필요한 트래픽낭비

=> 해결 : 리액트와 같은 라이브러리나 프레임워크를 사용하여 뷰 렌더링을 유저의 웹브라우저가 담당하도록하고, app을 우선 웹 브라우저에 로드시킨 후 필요한 데이터만 전달

 

- SPA

: 서버에서 제공하는 페이지가 하나이지만, 웹브라우저에서 나머지 페이지들을 정의. 다른 페이지로 이동할 때는 서버에 새로운 페이지를 요청하는 것이 아니라, 새 페이지에서 필요한 데이터만 받아 와 그에 따라 웹브라우저가 다른 종류의 뷰를 만든다.

 

- routing

: 주소에 따라 다른 뷰를 보여주는 것

 

- react-router

: 서드 파티 라이브러리로, 페이지 주소를 변경했을 때 주소에 따라 다른 컴포넌트를 렌더링하고, 주소정보를 컴포넌트의 props로 전달해서 컴포넌트 단에서 주소 상태에 따라 다른 작업을 하도록 설정가능

 

2. react-router 라이브러리를 이용한 SPA 개발

2-1. 프로젝트 생성및 컴포넌트 준비

$ create-react-app react-router-project
$ yarn add creat-router-dom

 

2-2. 컴포넌트 준비

//src/App.js
import React from 'react';

function App() {
  return (
    <div className="App">
    	react-router
    </div>
  );
}

export default App;

 

//src/Root.js
import React from 'react';
import App from './App';

//BrowserRouter : HTML$의 history api를 사용하여 새로고침하지 않고도 페이지 주소를 교체
import {BrowserRouter} from 'react-router-dom'; 

const Root = () => {
    return (
        <BrowserRouter> 
            <App />
        </BrowserRouter>
    );
};

export default Root;

 

//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Root from './Root';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<Root />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

 

2-3. 기본 라우트 설정

//src/pages/Home.js
import React from 'react';

const Home = () => {
    return (
        <div>
            <h1>HOME</h1>
        </div>
    );
};

export default Home;

 

//src/pages/About.js
import React from 'react';

const About = () => {
    return (
        <div>
            <p>this is about page</p>
        </div>
    );
};

export default About;

 

export {default as Home} from './Home';
export {default as About} from './About';

 

//src/App.js
import React from 'react';

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

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

export default App;

 

2-4. 라우트 파라미터와 쿼리 읽기

//src/App.js
import React from 'react';

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

function App() {
  return (
    <div className="App">
      <Route exact path="/" component={Home} />
      <Route path="/about/:name?" component={About} /> 
    </div>
  );
}

export default App;

- params를 지정할 때는 :key형식으로 설정

- :name값을 선택적으로 입력받을 수 있게 뒷부분에 ?를 입력

//src/pages/About.js

import React from 'react';
import queryString from 'query-string';

const About = ({location, match}) => {
    const query = queryString.parse(location.search);
    const {color} = query //const color = query.color;

    return (
        <div>
            <h1 style={{color}}>About</h1>
            <p>this is about page</p>
            <p>params : {match.params.name}</p>
        </div>
    );
};

export default About;

- query-string 라이브러리는 문자열로 된 쿼리를 객체 형태로 파싱

 

2-5. 라우터이동 : Link컴포넌트, NavLink 컴포넌트, 자바스크립트에서 라우팅

//src/components/Menu.js
import React from 'react';
import {Link} from 'react-router-dom';
import {NavLink} from 'react-router-dom';

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

    return (
        <div>
            <ul>
                <li><Link to="/">HOME</Link></li>
                <li><Link to="/about">ABOUT</Link></li>
                <li><Link to="/about/react">ABOUT REACT</Link></li>
                <li><a href="/about">ABOUT with 새로고칭</a></li>
                <li><a href="/about/react">ABOUT REACT with 새로고칭</a></li>
                <li><NavLink exact to="/" activeStyle={activeStyle}>HOME</NavLink></li>
                <li><NavLink exact to="/about" activeStyle={activeStyle}>ABOUT</NavLink></li>
                <li><NavLink exact to="/about/react" activeStyle={activeStyle}>ABOUT REACT</NavLink></li>
            </ul>
        </div>
    )
};

export default Menu;

- <a href>...</a> : 페이지를 새로고침하면서 로딩

- Link 컴포넌트 : 페이지를 새로고침하여 불러오지 않고, 주소 창 상태를 변경하고 원하는 라우트로 화면을 전환

- NavLink 컴포넌트 : 현재주소와 해당 컴포넌트의 목적지 주소가 일치하면 특정스타일 또는 클래스 지정 가능

 

//src/pages/Home.js
import React from 'react';

const Home = ({history}) => {
    return (
        <div>
            <h1>HOME</h1>
            <button onClick={()=>{history.push('./about/JS')}}>JS로 라우팅</button>
        </div>
    );
};

export default Home;

 

2-6. 서브라우터 : 라우트 안의 라우트 

//src/components/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}>HOME</NavLink></li>
                <li><NavLink exact to="/about" activeStyle={activeStyle}>ABOUT</NavLink></li>
                <li><NavLink exact to="/about/react" activeStyle={activeStyle}>ABOUT REACT</NavLink></li>
                <li><NavLink exact to="/postList" activeStyle={activeStyle}>POST LIST</NavLink></li>
            </ul>
        </div>
    )
};

export default Menu;

 

//src/App.js
import React from 'react';
import Menu from './components/Menu';

// router
import {Route} from 'react-router-dom';
import {Home, About, PostList} from './pages';

function App() {
  return (
    <div className="App">
      <Menu />
      <Route exact path="/" component={Home} />
      <Route path="/about/:name?" component={About} />
      <Route path="/postList" component={PostList} />
    </div>
  );
}

export default App;

 

//src/pages/PostList.js
import React from 'react';
import { Post } from 'pages';
import { Link, Route } from 'react-router-dom';

const PostList = ({ match }) => {
    return (
        <div>
            <h2>POST LIST</h2>
            <ul>
                <li><Link to={`${match.url}/1`}>POST #1</Link></li>
                <li><Link to={`${match.url}/2`}>POST #2</Link></li>
                <li><Link to={`${match.url}/3`}>POST #3</Link></li>
            </ul>
            <Route exact path={match.url} render={() => (<p>choose a post</p>)} />
            <Route exact path={`${match.url}/:id`} component={Post} />
        </div>
    );
};

export default PostList;

 

//src/pages/Post.js
import React from 'react';

const Post = ({match}) => {

    return (
        <div>
            <p>포스트 id : {match.params.id}</p>
        </div>
    );
};

export default Post;

 

//src/pages/index.js
export {default as Home} from './Home';
export {default as About} from './About';
export {default as Post} from './Post';
export {default as PostList} from './PostList';

 

2-7. 라우트로 사용된 컴포넌트가 전달받는 props : location, match, history

 

- location.pathname 은 현재 브라우저상의 위치를 알려줍니다. 이 값은 어떤 라우트에서 렌더링하던 동일합니다.

- match 관련은 설정한 Route 와 직접적으로 관계된 값만 보여줍니다.

  • Posts 를 보여주는 라우트에선 :id 값을 설정하지 않았으니 path 와 url 이 둘다 /posts 입니다.
  • Post 를 보여주는 라우트에선 path 의 경우엔 라우트에서 설정한 path 값이 그대로 나타납니다. url 의 경우엔 :id 부분에 값이 들어간 상태로 나타납니다.- histroy는 현재 라우터를 조작할 때 사용

'Javascript > React' 카테고리의 다른 글

#3 React Event Handling  (0) 2020.02.12
#2 React Component  (0) 2020.02.12
#1 basic react  (0) 2020.02.12
#0 React intro  (0) 2020.02.12
webpack - resolve  (0) 2019.09.03
Posted by yongminLEE