react-03

1. 理解react-router

react的一個插件庫
專門用來實現一個SPA應用
基於react的項目基本都會用到此庫

2. 幾個重要問題

1). SPA應用

單頁Web應用(single page web application,SPA)
整個應用只有一個完整的頁面
點擊頁面中的連接不會刷新頁面, 自己也不會向服務器發請求
當點擊連接時, 只會作頁面的局部更新
數據都須要經過ajax請求獲取, 並在前端異步展示

2). 路由

1. 什麼是路由?
	一個路由就是一個映射關係(key:value)
	key爲路由路徑, value多是function/component
2. 路由分類
	後臺路由: node服務器端路由, value是function, 用來處理客戶端提交的請求並返回一個響應數據
	前臺路由: 瀏覽器端路由, value是component, 當請求的是路由path時, 瀏覽器端前沒有發送http請求, 但界面會更新顯示對應的組件 
3. 後臺路由
	* 註冊路由: router.get(path, function(req, res))
	* 當node接收到一個請求時, 根據請求路徑找到匹配的路由, 調用路由中的函數來處理請求, 返回響應數據
* 前端路由
	* 註冊路由: <Route path="/about" component={About}>
	* 當瀏覽器的hash變爲#about時, 當前路由組件就會變爲About組件

3). 關於url中的#

1. 理解#
	'#'表明網頁中的一個位置。其右面的字符,就是該位置的標識符
	改變#不觸發網頁重載
	改變#會改變瀏覽器的訪問歷史
2. 操做#
	window.location.hash讀取#值
	window.onhashchange = func 監聽hash改變
3. 學習資源: 
	阮一峯教程: http://www.ruanyifeng.com/blog/2011/03/url_hash.html

3. react-router的學習資源

github主頁: https://github.com/ReactTraining/react-router
官網教程: https://github.com/reactjs/react-router-tutorial
阮一峯教程: http://www.ruanyifeng.com/blog/2016/05/react_router.html

4. 相關API

1). react-router中的相關組件:

Router: 路由器組件, 用來包含各個路由組件
Route: 路由組件, 註冊路由 
IndexRoute: 默認子路由組件
hashHistory: 路由的切換由URL的hash變化決定,即URL的#部分發生變化
Link: 路由連接組件

2). Router: 路由器組件

屬性:  history={hashHistory} 用來監聽瀏覽器地址欄的變化, 並將URL解析成一個地址對象,供React Router匹配
子組件: Route

3). Route: 路由組件

屬性1: path="/xxx"  
屬性2: component={Xxx}
根路由組件: path="/"的組件, 通常爲App
子路由組件: 子<Route>配置的組件

4). IndexRoute: 默認路由

當父路由被請求時, 默認就會請求此路由組件

5). hashHistory

用於Router組件的history屬性
做用: 爲地址url生成?_k=hash, 用於內部保存對應的state

6). Link: 路由連接

屬性1: to="/xxx"
屬性2: activeClassName="active"

5. react-router的基本使用

1). 下載

npm install react-router --save

2). 定義各個路由組件

1. About.js
  import React from 'react'
  function About() {
    return <div>About組件內容</div>
  }
  export default About
2. Home.js
  import React from 'react'
  function Home() {
    return <div>Home組件內容2</div>
  }
  export default Home
3. Repos.js
  import React, {Component} from 'react'
  export default class Repos extends Component {
    render() {
      return (
        <div>Repos組件</div>
      )
    }
  }
4. App.js
import React, {Component} from 'react'
import {Link} from 'react-router'

export default class App extends Component {
  render() {
    return (
      <div>
        <h2>Hello, React Router!</h2>
        <ul>
          <li><Link to="/about" activeClassName="active">About2</Link></li>
          <li><Link to="/repos" activeClassName="active">Repos2</Link></li>
        </ul>
        {this.props.children}
      </div>
    )
  }
}

3). index.js: 註冊路由, 渲染路由器標籤

import React from 'react'
import {render} from 'react-dom'
import {Router, Route, IndexRoute, hashHistory} from 'react-router'
import App from './modules/App'
import About from './modules/About'
import Repos from './modules/Repos'
import Home from './modules/Home'

render((
  <Router history={hashHistory}>
    <Route path="/" component={App}>
      <IndexRoute component={Home}/>
      <Route path="/about" component={About}></Route>
      <Route path="/repos" component={Repos}></Route>
    </Route>
  </Router>
), document.getElementById('app'))

3). 主頁面: index.html

<style>
  .active {
    color: red;
  }
</style>

6. 向路由組件傳遞請求參數

1). repo.js: repos組件下的分路由組件

import React from 'react'
export default function ({params}) {
  let {username, repoName} = params
  return (
    <div>用戶名:{username}, 倉庫名:{repoName}</div>
  )
}

2). repos.js

import React from 'react'
import NavLink from './NavLink'

export default class Repos extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      repos: [
        {username: 'faceback', repoName: 'react'},
        {username: 'faceback', repoName: 'react-router'},
        {username: 'Angular', repoName: 'angular'},
        {username: 'Angular', repoName: 'angular-cli'}
      ]
    };
    this.handleSubmit = this.handleSubmit.bind(this)
  }

  handleSubmit () {

    const repos = this.state.repos
    repos.push({
      username: this.refs.username.value,
      repoName: this.refs.repoName.value
    })
    this.setState({repos})
    this.refs.username.value = ''
    this.refs.repoName.value = ''
  }

  render() {
    return (
      <div>
        <h2>Repos</h2>
        <ul>
          {
            this.state.repos.map((repo, index) => {
              const to = `/repos/${repo.username}/${repo.repoName}`
              return (
                <li key={index}>
                  <Link to={to} activeClassName='active'>{repo.repoName}</Link>
                </li>
              )
            })
          }
          <li>
            <form onSubmit={this.handleSubmit}>
              <input type="text" placeholder="用戶名" ref='username'/> / {' '}
              <input type="text" placeholder="倉庫名" ref='repoName'/>{' '}
              <button type="submit">添加</button>
            </form>
          </li>
        </ul>
        {this.props.children}
      </div>
    );
  }
}

3). index.js: 配置路由

<Route path="/repos" component={Repos}>
  <Route path="/repos/:username/:repoName" component={Repo}/>
</Route>

7. 優化Link組件

1). NavLink.js

import React from 'react'
import {Link} from 'react-router'
export default function NavLink(props) {
  return <Link {...props} activeClassName="active"/>
}

2). Repos.js

<NavLink to={to}>{repo.repoName}</NavLink>
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息