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 |