react router - slahsk/study GitHub Wiki

๋ผ์šฐํŒ…

๊ธฐ๋ณธ์ ์ธ ๋ผ์šฐํŒ…

import React, { Component } from 'react';
import { render } from 'react-dom';


import About from './About';
import Home from './Home';
import Repos from './Repos';

class App extends Component{
  constructor(){
    super(...arguments);
    this.state ={
      route : window.location.hash.substr(1)
    };
  }

  componentDidMount(){
    window.addEventListener('hashchange', () => {
      this.setState({
          route:window.location.hash.substr(1)
      });
    });
  }

  render(){
    var Child;
    switch (this.state.route) {
      case '/about':Child = About;break;
      case '/repos':Child = Repos;break;
      default:Child = Home;
    }

    return(
      <div>
          <header>App</header>
          <menu>
            <ul>
              <li><a href="#/about">About</a></li>
              <li><a href="#/repos">Repos</a></li>
            </ul>
          </menu>
          <Child/>
      </div>
    );

  }

}

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

์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ๋  ๋•Œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ถ”๊ฐ€ํ•ด URL ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค route ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๊ฒŒ ํ•œ๋‹ค.

๋ฌธ์ œ์ 

  • URL ๊ด€๋ฆฌ๊ฐ€ ํ•ต์‹ฌ์ ์ธ ์ž‘์ž…์ด ๋๋‹ค.
  • ์ง์ ‘ URL์„ ์ˆ˜์‹ ํ•˜๊ณ  ์กฐ์ž‘
  • ๋ผ์šฐํŒ… ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

React Router

  • ์ค‘์ฒฉ๋œ URL๊ณผ ์ค‘์ฒฉ๋œ ์ปดํฌ๋„ŒํŠธ ๊ณ„์ธต์€ ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ์˜ ์„ ์–ต์‹ API์—์„œ ํ•ต์‹ฌ์ ์ธ ๊ฐœ๋…์ด๋ฉฐ, ๋ฆฌ์•กํŠธ ์ฝ”์–ด์˜ ์ผ๋ถ€๋Š” ์•„๋‹ˆ์ง€๋งŒ ๋ฆฌ์•กํŠธ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ํ‘œ์ค€์œผ๋กœ ์ธ์ • ๋ฐ›๊ณ  ์žˆ๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ค‘์ฒฉ ๋‹จ๊ณ„์— ๊ด€๊ณ„์—†์ด ๋ผ์šฐํŠธ์™€ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ UI๋ฅผ URL๊ณผ ๋™๊ธฐํ™” ํ•œ๋‹ค.
  • URL์„ ๋ณ€๊ฒฝํ•˜๋ฉด ์ž๋™์œผ๋กœ ์–ธ๋งˆ์šดํŠธ ๋ฐ ๋งˆ์šดํŠธ ๋œ๋‹ค.
import React, { Component } from 'react';
import { render } from 'react-dom';
import { Router, Route, Link, browserHistory , IndexRoute} from 'react-router';


import './style.css';


import About from './About';
import Home from './Home';
import Repos from './Repos';
import RepoDetails from './RepoDetails';
import ServerError from './ServerError';

class App extends Component{

  render(){
    return(
      <div>
          <header>App</header>
          <menu>
            <ul>
              <li><Link to="/about" activeClassName="active">About</Link></li>
              <li><Link to="/repos" activeClassName="active">Repos</Link></li>
            </ul>
          </menu>
          {this.props.children}
      </div>
    );

  }

}

render((
  <Router history={browserHistory} >
    <Route path="/" component={App}>
      <IndexRoute component={Home} />
      <Route path="about" component={About} title="About Us"/>
      <Route path="repos" component={Repos}>
        {/* <Route path="details/:repo_name" component={RepoDetails}/> */}
        <Route path="/repo/:repo_name" component={RepoDetails}/>
      </Route>
      <Route path="error" component={ServerError} />
    </Route>
  </Router>
), document.getElementById('root'));

์ธ๋ฑ์Šค ๋ผ์šฐํŠธ

/ ๋ผ์šฐํŠธ์—ฅ์„œ ์„œ๋ฒ„์— ์ ‘๊ทผํ•˜๋ฉด ์ž์‹์ด ์—†๋Š” App ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋œ๋‹ค.

<IndexRoute component={Home} />

๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•˜๋Š” ๋ผ์šฐํŠธ

<Route path="/repo/:repo_name" component={RepoDetails}/>

  • :repo_name ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ปดํฌ๋„ŒํŠธ์˜ ์†์„ฑ์— ์ฃผ์ž…ํ•œ๋‹ค.
  • RepoDetails ์—์„œ componentWillReceiveProps ๋ผ๋Š” ์ถ”๊ฐ€ ์ˆ˜๋ช…์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ์—์„œ๋„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•œ๋‹ค. ๋งˆ์šดํŒ…๋œ ํ›„์—๋„ ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค๋ฅธ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ƒˆ๋กœ์šด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ๋ฉฐ ์ด๊ฒฝ์šฐ componentDidMount ๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๊ณ  componentWillReceiveProps๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
componentDidMount(){


  let repo_name = this.props.params.repo_name;

  this.fetchData(repo_name);
}

componentWillReceiveProps(nextProps){
  let repo_name = nextProps.params.repo_name;

  this.fetchData(repo_name);
}

์†์„ฑ ์ „๋‹ฌํ•˜๊ธฐ

<Route path="about" component={About} title="About Us"/> ์ „๋‹ฌํ•˜๋ฉด {this.props.route.title} ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

๋™์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” {this.props.children} ๊ทธ๋Œ€๋กœ ๋ Œ๋”๋งํ•˜๋Š” ๋Œ€์‹  ์ด๋ฅผ ๋ณต์ œํ•˜๊ณ  ์ถ”๊ฐ€ ์†์„œ์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค.

let child = this.props.children && React.cloneElement(this.props.children, {
  repositories : this.state.repositories
});

https://github.com/ReactTraining/react-router/blob/master/docs/API.md

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ๋ผ์šฐํŠธ ๋ณ€๊ฒฝ

Link ์ปดํฌ๋„ŒํŠธ๋Š” ์ตœ์ข… ์‚ฌ์šฉ์ž๊ฐ€ ๋ผ์šฐํŠธ์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ํ›Œ๋ฅญํ•œ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ ์ข…์ข… ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ๋ผ์šฐํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์ฆ‰, ํŠน์ •ํ•œ ์ƒํ™ฉ์—์„œ ์ž๋™์œผ๋กœ ์ด์ „์œผ๋กœ ๋Œ์•„๊ฐ€๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž๋Š” ๋‹ค๋ฅธ ๋ผ์šฐํŠธ๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ชฉ์ ์œผ๋กœ ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ๋Š” ๋งˆ์šดํŒ…ํ•˜๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์— ์ž๋™์œผ๋กœ ์ž์ฒด history ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•œ๋‹ค

history ๊ฐ์ฒด๋Š” ๋ถ€๋ผ์šฐ์ €์˜ ํžˆ์Šคํ† ๋ฆฌ ์Šคํƒ์„ ๊ด€๋ฆฌํ•˜๋Š” ์—ญํ™œ์„ ํ•œ๋‹ค.

๋ฉ”์„œ๋“œ ์„ค๋ช…
pushState ์ƒˆ๋กœ์šด URL๋กœ ์ด๋™ํ•˜๋Š” ๊ธฐ๋ณธ ํžˆ์Šคํ† ๋ฆฌ ํƒ์ƒ‰ ๋ฉ”์„œ๋“œ์ด๋ฉฐ ์˜ต์…˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
history.pushState(null, '/users/123')
history.pushState({showGrades:true},'/users/123')
replaceState pushState์™€ ๋™์ผํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉฐ ํ˜„์žฌ URL์„ ์ƒˆ๋กœ์šด URL๋กœ ๋Œ€์ฒดํ•œ๋‹ค
ํžˆ์Šคํ† ๋ฆฌ์˜ ๊ธธ์ด์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ  URL์„ ๋Œ€์ฒดํ•œ๋‹ค๋Š” ์ ์—์„œ ๋ฆฌ๋””๋ ‰์…˜๊ณผ ๋น„์Šทํ•˜๋‹ค.
goBack ํƒ์ƒ‰ ํžˆ์Šคํ† ๋ฆฌ์—์„œ ํ•œ ํ•ญ๋ชฉ ๋’ค๋กœ ์ด๋™ํ•œ๋‹ค.
goForward ํƒ์ƒ‰ ํžˆ์Šคํ† ๋ฆฌ์—์„œ ํ•œ ํ•ญ๋ชฉ ์•ž์œผ๋กœ ์ด๋™ํ•œ๋‹ค.
Go n ๋˜๋Š” -n๋งŒํผ ์•ž์œผ๋กœ ๋˜๋Š” ๋’ค๋กœ ์ด๋™ํ•œ๋‹ค.
createHref ๋ผ์šฐํ„ฐ์˜ ๊ตฌ์„ฑ์„ ์ด์šฉํ•ด URL์„ ๋งŒ๋“ ๋‹ค.

react-router 2.0

// v1.x
<Router/>

// v2.0.0
// hash history
import { hashHistory } from 'react-router'
<Router history={hashHistory} />
// v1.x
import createBrowserHistory from 'history/lib/createBrowserHistory'
<Router history={createBrowserHistory()} />

// v2.0.0
import { browserHistory } from 'react-router'
<Router history={browserHistory} />
// v1.0.x
history.pushState(state, path, query)
history.replaceState(state, path, query)

// v2.0.0
router.push(path)
router.push({ pathname, query, state }) // new "location descriptor"

router.replace(path)
router.replace({ pathname, query, state }) // new "location descriptor"

https://github.com/ReactTraining/react-router/blob/master/upgrade-guides/v2.0.0.md

โš ๏ธ **GitHub.com Fallback** โš ๏ธ