react-router

1. Router,hashHistory,Route

首先下載react-routercss

$ npm install react-router --save

須要注意的是,react-router更新很快,API也在持續升級,也許你看到市面不少教程,但可能那仍是1.x甚至是0.x版本的。react

咱們首先在App.jsx寫一個簡單示例,讓你快速的對react-router有印象。webpack

代碼清單:app/container/App/App.jsxweb

import React, { Component } from 'react';
import { Router, Route, hashHistory } from 'react-router';

const Home = () => <div><h1>Home</h1></div>;
const About = () => <div><h1>About</h1></div>;
const Contact = () => <div><h1>Contact</h1></div>;

class App extends Component {
  render() {
    return (
      <Router history={hashHistory}>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
      </Router>
    );
  }
}

export default App;

2. Link

Link是react-router提供的導航組件,能夠直接使用進行路由切換npm

代碼清單:app/container/App/App.jsxapi

import React, { Component } from 'react';
import { Router, Route, hashHistory, Link } from 'react-router';

const Home = () => <div><h1>Home</h1><Links /></div>;
const About = () => <div><h1>About</h1><Links /></div>;
const Contact = () => <div><h1>Contact</h1><Links /></div>;

const Links = () =>
  <nav>
    <Link to="/">Home</Link>
    <Link to="/about">About</Link>
    <Link to="/contact">Contact</Link>
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={hashHistory}>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
      </Router>
    );
  }
}

export default App;

3. browserHistory

browserHistory和hashHistory不同,使用browserHistory的時候,瀏覽器中導航欄的URL就不會出現_k的hash鍵值對。實際項目中也通常用browserHistory.瀏覽器

import React, { Component } from 'react';
import { Router, Route, browserHistory, Link } from 'react-router';

const Home = () => <div><h1>Home</h1><Links /></div>;
const About = () => <div><h1>About</h1><Links /></div>;
const Contact = () => <div><h1>Contact</h1><Links /></div>;

const Links = () =>
  <nav>
    <Link to="/">Home</Link>
    <Link to="/about">About</Link>
    <Link to="/contact">Contact</Link>
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={browserHistory}>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
      </Router>
    );
  }
}

export default App;

這樣正常點擊路由切換沒有問題,可是從新刷新URL就會報找不到路由,這個時候咱們在webpack-dev-server啓動的時候須要加上參數--history-api-fallback。react-router

4. activeStyle,activeClassName

當前路由被點擊處於觸發顯示狀態的時候,咱們可使用activeStyle來給路由設置一些顏色。app

import React, { Component } from 'react';
import { Router, Route, browserHistory, Link } from 'react-router';

const Home = () => <div><h1>Home</h1><Links /></div>;
const About = () => <div><h1>About</h1><Links /></div>;
const Contact = () => <div><h1>Contact</h1><Links /></div>;

const Links = () =>
  <nav>
    <Link activeStyle={{color: 'red'}} to="/">Home</Link>
    <Link activeStyle={{color: 'red'}} to="/about">About</Link>
    <Link activeStyle={{color: 'red'}} to="/contact">Contact</Link>
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={browserHistory}>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
      </Router>
    );
  }
}

export default App;

同理,咱們還可使用activeClassName來將路由激活狀態的樣式抽取出來。webpack-dev-server

咱們在App.css寫一個樣式,代碼清單:app/containers/App/App.jsx

.active {
  color: red;
}

而後修改App.jsx

import React, { Component } from 'react';
import { Router, Route, browserHistory, Link } from 'react-router';

import './App.css';

const Home = () => <div><h1>Home</h1><Links /></div>;
const About = () => <div><h1>About</h1><Links /></div>;
const Contact = () => <div><h1>Contact</h1><Links /></div>;

const Links = () =>
  <nav>
    <Link activeClassName="active" to="/">Home</Link>
    <Link activeClassName="active" to="/about">About</Link>
    <Link activeClassName="active" to="/contact">Contact</Link>
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={browserHistory}>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
      </Router>
    );
  }
}

export default App;

5. 路由嵌套

剛纔講的是簡單路由的切換,但實際應用中,路由是分多個層級的。幸運的是,咱們可使用react-router的路由嵌套來清晰的管理路由和組件之間的切換展現。

import React, { Component } from 'react';
import { Router, Route, browserHistory, Link } from 'react-router';

import './App.css';

const Home = (props) =>
  <div>
    <h1>Home</h1>
    <Links />
    {props.children}
  </div>

const About = (props) =>
  <div>
    <h1>About</h1>
    {props.children}
  </div>

const Contact = () =>
  <div>
    <h1>Contact</h1>
  </div>

const Links = () =>
  <nav>
    <Link activeClassName="active" to="/">Home</Link>
    <Link activeClassName="active" to="/about">About</Link>
    <Link activeClassName="active" to="/about/contact">Contact</Link>
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={browserHistory}>
        <Route path="/" component={Home}>
          <Route path="about" component={About}>
            <Route path="contact" component={Contact} />
          </Route>
        </Route>
      </Router>
    );
  }
}

export default App;

6. IndexRoute

IndexRoute即處理頁面初始進入時候的組件展現,等路由切換的時候,再根據其餘路由規則進行組件的切換展現。

import React, { Component } from 'react';
import { Router, Route, browserHistory, Link, IndexRoute } from 'react-router';

import './App.css';

const Home = (props) =>
  <div>
    <h1>Home</h1>
    <Links />
    {props.children}
  </div>

const About = () =>
  <div>
    <h1>About</h1>
  </div>

const Contact = () =>
  <div>
    <h1>Contact</h1>
  </div>

const Links = () =>
  <nav>
    <Link activeClassName="active" to="/">Home</Link>
    <Link activeClassName="active" to="/contact">Contact</Link>
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={browserHistory}>
        <Route path="/" component={Home}>
          <IndexRoute component={About} />
          <Route path="contact" component={Contact} />
        </Route>
      </Router>
    );
  }
}

export default App;

7. 路由變量

剛纔展現的是常規的路由,路由中的規則是給定的,如今咱們嘗試使用路由變量,在組件中獲取這個路由的變量,並作相應的組件展現。

import React, { Component } from 'react';
import { Router, Route, hashHistory, Link, IndexRoute } from 'react-router';

import './App.css';

const Message = (props) =>
  <div>
    <h1>{props.params.message || 'Hello'}</h1>
    <Links />
  </div>

const Links = () =>
  <nav>
    <Link to="/">Hello</Link>
    <Link to="/yong">Yong</Link>
    <Link to="/feng">Feng</Link>
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={hashHistory}>
        <Route path="/(:message)" component={Message} />
      </Router>
    );
  }
}

export default App;

8. Route中components參數的高級用法

Route中components中接收的參數不單單只是實際的組件,還能夠是對象,經過這樣的用法,咱們能夠更靈活的控制組件的展現。

import React, { Component } from 'react';
import { Router, Route, hashHistory, Link, IndexRoute } from 'react-router';

import './App.css';

const HomeHeader = () => <h1>HomeHeader</h1>
const HomeBody = () => <h1>HomeBody</h1>
const AboutHeader = () => <h1>AboutHeader</h1>
const AboutBody = () => <h1>AboutBody</h1>

const Container = (props) =>
  <div>
    {props.header}
    {props.body}
    <Links />
  </div>

const Links = () =>
  <nav>
    <Link to="/">Hello</Link>
    <Link to="/about">About</Link>
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={hashHistory}>
        <Route path="/" component={Container}>
          <IndexRoute components={{ header:HomeHeader, body:HomeBody }} />
          <Route path="about" components={{ header:AboutHeader, body:AboutBody }} />
        </Route>
      </Router>
    );
  }
}

export default App;

9. 使用query獲取URL中的參數

咱們能夠將URL中訪問的參數獲取,而且應用到組件中。

import React, { Component } from 'react';
import { Router, Route, hashHistory, Link, IndexRoute } from 'react-router';

import './App.css';

const Page = (props) =>
  <div>
    <h1>{props.location.query.message || 'Hello'}</h1>
  </div>

class App extends Component {
  render() {
    return (
      <Router history={hashHistory}>
        <Route path="/" component={Page} />
      </Router>
    );
  }
}

export default App;

而後在url中輸入http://localhost:8080/#/?message=guoyongfeng,頁面中就會顯示guoyongfeng。

另外,咱們還能夠在Link組件中設置pathname和query變量

import React, { Component } from 'react';
import { Router, Route, hashHistory, Link, IndexRoute } from 'react-router';

import './App.css';

const Page = (props) =>
  <div>
    <h1>{props.location.query.message || 'Hello'}</h1>
  </div>

const Links = () =>
  <nav>
    <Link to={{ pathname: "/", query: {message: "guoyongfeng"} }} />
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={hashHistory}>
        <Route path="/" component={Page} />
      </Router>
    );
  }
}

export default App;

10. Redirect重定向

import React, { Component } from 'react';
import { Router, Route, hashHistory, Link, Redirect } from 'react-router';

const Home = () => <div><h1>Home</h1><Links /></div>;
const About = () => <div><h1>About</h1><Links /></div>;
const Contact = () => <div><h1>Contact</h1><Links /></div>;

const Links = () =>
  <nav>
    <Link to="/">Home</Link>
    <Link to="/about">About</Link>
    <Link to="/contact">Contact</Link>
    <Link to="/contact-us">Contact US</Link>
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={hashHistory}>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact-us" component={Contact} />
        <Redirect from="/contact" to="/contact-us" />
      </Router>
    );
  }
}

export default App;

11. setRouteLeaveHook路由鉤子函數:處理路由切換時的操做

import React, { Component, PropTypes } from 'react';
import { Router, Route, hashHistory, Link } from 'react-router';

class Home extends Component {
  componentWillMount(){
    this.context.router.setRouteLeaveHook(
      this.props.route,
      this.routerWillLeave
    )
  }
  routerWillLeave( nextLocation ){
    return `頁面即將從Home切換到${nextLocation.pathname}`
  }
  render(){
    return <div>
      <h1>Home</h1>
      <Links />
    </div>
  }
}

Home.contextTypes = {
  router: PropTypes.object.isRequired
};

const Contact = () => <div><h1>Contact</h1><Links /></div>;

const Links = () =>
  <nav>
    <Link to="/">Home</Link>
    <Link to="/contact">Contact</Link>
  </nav>

class App extends Component {
  render() {
    return (
      <Router history={hashHistory}>
        <Route path="/" component={Home} />
        <Route path="/contact" component={Contact} />
      </Router>
    );
  }
}

export default App;
相關文章
相關標籤/搜索