react-router4.0路由說明


React Router 4.0 (以下簡稱 RR4) 已經正式發布,它遵循react的設計理念,即萬物皆組件。所以 RR4 只是一堆 提供了導航功能的組件(還有若干對象和方法),具有聲明式(引入即用),可組合性的特點。http://www.jianshu.com/p/e3adc9b5f75c

RR4 本次采用單代碼倉庫模型架構(monorepo),這意味者這個倉庫里面有若干相互獨立的包,分別是:

  • react-router React Router 核心
  • react-router-dom 用於 DOM 綁定的 React Router
  • react-router-native 用於 React Native 的 React Router
  • react-router-redux React Router 和 Redux 的集成
  • react-router-config 靜態路由配置的小助手

最新版的React Router(v4)有以下幾個發行包,可能從之前版本用過來的同學會有一些疑惑,我到底該用哪一個啊?

react-router

React Router 的核心公用組件和方法。具體如下: MemoryRouter、 Prompt、 Redirect、 Route、 RouterStaticRouter、 Switch、 matchPath、 withRouter

react-router-dom

React Router for WEB,一般我們前端就用這個包來進行WEB開發了,提供包括上述react-router相關的組件和方法以外還有如下接口:
BrowserRouter、 HashRouter、 Link 、NavLink

react-router-native

React Router 給react-native提供額外路由相關支持,包括:NativeRouter、 Link、 DeepLinkingAndroidBackButton,感興趣的同學可以訪問這里 https://reacttraining.com/react-router/native/guides/quick-start 研究下。

react-router-redux

最新的版本還在測試版本中,如果你項目里面同時用到了react-router 和 redux,然后想把各種路由狀態存儲在app的狀態里面,就可以用這個庫了。這個庫也輔助的,操作路由切換,如: dispatch( push('/xx') )

react-router-config

該包主要提供如下接口:matchRoutesrenderRoutes,官方說明 https://github.com/ReactTraining/react-router/tree/master/packages/react-router-config

從React Router V4 開始,APP路由配置就不需要集中到一個地方了。但有些情況下我們還是需要集中配置一些路由,這個包就是來輔助做這些的,它嘗試建立一種共享的模式,讓上層應用基於它來構建這些路由配置。

綜上,再也不用糾結該用哪個包了,每個包都有些什么了,如果不是做native相關的就用 react-router-dom,如果你是做react-native相關的應用就毫不猶豫的選擇用 react-router-native來構建你的應用路由咯。

 

原文來自:https://fiture.me/share/javascript/1254.html

引用react-router 還是 react-router-dom?

然后在React的使用中,我們一般要引入兩個包,react和react-dom;那么react-router 和react-router-dom是不是兩個都要引用呢?

不是,兩者引用一個就行了,不同之處就是后者比前者多出了<Link><BrowserRouter>這樣的DOM類組件。

因此我們只需要引用reac-router-dom這個包就行了,當然,如果要搭配redux,你還需要使用react-router-redux

reac-router-dom組件說明

<BrowserRouter>

一個使用了 HTML5 history API 的高階路由組件,保證你的 UI 界面和 URL 保持同步。此組件擁有以下屬性:

basename: string
作用:為所有位置添加一個基准URL
使用場景:假如你需要把頁面部署到服務器的二級目錄,你可以使用 basename 設置到此目錄。

<BrowserRouter basename="/minooo" />
<Link to="/react" /> // 最終渲染為 <a href="/minooo/react">

BrowserRouter詳細說明:http://blog.csdn.net/sinat_17775997/article/details/69218382

其中,HashRouter和BrowserRouter的區別使用

從上面動圖可以看出:當我們刷新瀏覽器的時候 就出問題了。

現在我們把BrowserRouter改成HashRouter,

主要引入的包不同

import {
    BrowserRouter as Router,
    Route,
    Link
} from 'react-router-dom';

#改為
import {
    HashRouter as Router,
    Route,
    Link
} from 'react-router-dom'

就是把BrowserRouter改成HashRouter即可。

現在刷新瀏覽器就不會出錯了。

import React, { Component } from 'react';
import { HashRouter, Switch, Route, Redirect } from 'react-router-dom';
import asyncComponent from '@/utils/asyncComponent';

import home from "@/pages/home/home";
const record = asyncComponent(() => import("@/pages/record/record"));
const helpcenter = asyncComponent(() => import("@/pages/helpcenter/helpcenter"));
const production = asyncComponent(() => import("@/pages/production/production"));
const balance = asyncComponent(() => import("@/pages/balance/balance"));
 
// react-router4 不再推薦將所有路由規則放在同一個地方集中式路由,子路由應該由父組件動態配置,組件在哪里匹配就在哪里渲染,更加靈活
export default class RouteConfig extends Component{
  render(){
    return(
      <HashRouter>
        <Switch>
          <Route path="/" exact component={home} />
          <Route path="/record" component={record} />
          <Route path="/helpcenter" component={helpcenter} />
          <Route path="/production" component={production} />
          <Route path="/balance" component={balance} />
          <Redirect to="/" />
        </Switch>
      </HashRouter>
    )
  }
}

 

原文來自:http://blog.csdn.net/github_26672553/article/details/76906488

<Route>

<Route> 也許是 RR4 中最重要的組件了,重要到你必須理解它,學會它,用好它。它最基本的職責就是當頁面的訪問地址與 Route 上的 path 匹配時,就渲染出對應的 UI 界面。

<Route> 自帶三個 render method 和三個 props 。

render methods 分別是:

  • <Route component>
  • <Route render>
  • <Route children>
    每種 render method 都有不同的應用場景,同一個<Route> 應該只使用一種 render method ,大部分情況下你將使用 component 。

props 分別是:

    • match
    • location
    • history
      所有的 render method 無一例外都將被傳入這些 props。

component
只有當訪問地址和路由匹配時,一個 React component 才會被渲染,此時此組件接受 route props (match, location, history)。
當使用 component 時,router 將使用 React.createElement 根據給定的 component 創建一個新的 React 元素。這意味着如果你使用內聯函數(inline function)傳值給 component將會產生不必要的重復裝載。對於內聯渲染(inline rendering), 建議使用 renderprop。

<Route path="/user/:username" component={User} />
const User = ({ match }) => {
  return <h1>Hello {match.params.username}!</h1>
}

render: func

此方法適用於內聯渲染,而且不會產生上文說的重復裝載問題。

// 內聯渲染
<Route path="/home" render={() => <h1>Home</h1} />

// 包裝 組合
const FadingRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    <FadeIn>
      <Component {...props} />
    </FaseIn>
  )} />
)

<FadingRoute path="/cool" component={Something} />
<Route path="/detail/:kerwinId" render={props=>
       <Detail {...props} kerwin="ok" />
 }>
</Route>

<Route path='/detail/:id' render={props => (
                  <Detail props={props}/>
                )}/>
                <Route path='/search/:category/:keyword?' render={props => (
                  <Search props={props}/>
                )}/>
                <Route path='/css' render={props => (
                  <CSS props={props}/>
                )}/>
                <Route path='/js' render={props => (
                  <JS props={props}/>
                )}/>
                <Route render={props => (
                  <NotFound props={props}/>
                )}/>

path: string
任何可以被 path-to-regexp解析的有效 URL 路徑

<Route path="/users/:id" component={User} />

Route詳細說明:http://blog.csdn.net/sinat_17775997/article/details/69218382

<Link>

為你的應用提供聲明式,無障礙導航。

to: string
作用:跳轉到指定路徑
使用場景:如果只是單純的跳轉就直接用字符串形式的路徑。

<Link to="/courses" />

to: object
作用:攜帶參數跳轉到指定路徑
作用場景:比如你點擊的這個鏈接將要跳轉的頁面需要展示此鏈接對應的內容,又比如這是個支付跳轉,需要把商品的價格等信息傳遞過去。

<Link to={{
  pathname: '/course',
  search: '?sort=name',
  state: { price: 18 }
}} />

replace: bool
為 true 時,點擊鏈接后將使用新地址替換掉上一次訪問的地址,什么意思呢,比如:你依次訪問 '/one' '/two' '/three' ’/four' 這四個地址,如果回退,將依次回退至 '/three' '/two' '/one' ,這符合我們的預期,假如我們把鏈接 '/three' 中的 replace 設為 true 時。依次點擊 one two three four 然后再回退會發生什么呢?會依次退至 '/three' '/one'! 為此我做了個在線 demo,大家可以調試體會一下 !

Link詳細說明:http://blog.csdn.net/sinat_17775997/article/details/69218382

<NavLink>

這是 <Link> 的特殊版,顧名思義這就是為頁面導航准備的。因為導航需要有 “激活狀態”。

activeClassName: string
導航選中激活時候應用的樣式名,默認樣式名為 active

<NavLink
  to="/about"
  activeClassName="selected"
>MyBlog</NavLink>

activeStyle: object
如果不想使用樣式名就直接寫style

<NavLink
  to="/about"
  activeStyle={{ color: 'green', fontWeight: 'bold' }}
>MyBlog</NavLink>

exact: bool
若為 true,只有當訪問地址嚴格匹配時激活樣式才會應用

strict: bool
若為 true,只有當訪問地址后綴斜杠嚴格匹配(有或無)時激活樣式才會應用

isActive: func
決定導航是否激活,或者在導航激活時候做點別的事情。不管怎樣,它不能決定對應頁面是否可以渲染。

NavLink詳細說明:http://blog.csdn.net/sinat_17775997/article/details/69218382

例子:

<NavLink to={`${this.props.match.path}/passed`} className="nav-link">已通過</NavLink>
<NavLink to={`${this.props.match.path}/audited`} className="nav-link">待審核</NavLink>
<NavLink to={`${this.props.match.path}/failed`} className="nav-link">未通過</NavLink>

 

import React, { Component } from 'react';
import { NavLink, Switch, Route, Redirect } from 'react-router-dom';
import PublicHeader from '@/components/header/header';
import RecordList from './components/recordList';
import './record.css';

class Record extends Component {
  state = {
    flagBarPos: '17%',
  }
  /**
   * 設置頭部底部標簽位置
   * @param  {string} type 數據類型
   */
  setFlagBarPos = type => {
    let flagBarPos;
    switch(type){
      case 'passed':
        flagBarPos = '17%';
      break;
      case 'audited':
        flagBarPos = '50%';
      break;
      case 'failed':
        flagBarPos = '83%';
      break;
      default: 
        flagBarPos = '17%';
    }
    this.setState({flagBarPos})
  }

  componentWillMount(){
    // 初始化設置頭部底部標簽位置
    let type = this.props.location.pathname.split('/')[2];
    this.setFlagBarPos(type);
  }
  render() {
    return (
      <main className="common-con-top">
        <PublicHeader title='記錄' />
        <section className="record-nav-con">
          <nav className="record-nav">
            <NavLink to={`${this.props.match.path}/passed`} className="nav-link">已通過</NavLink>
            <NavLink to={`${this.props.match.path}/audited`} className="nav-link">待審核</NavLink>
            <NavLink to={`${this.props.match.path}/failed`} className="nav-link">未通過</NavLink>
          </nav>
          <i className="nav-flag-bar" style={{left: this.state.flagBarPos}}></i>
        </section>
        {/* 子路由在父級配置,react-router4新特性,更加靈活 */}
        <Switch>
          <Route path={`${this.props.match.path}/:type`} component={RecordList} />
          <Redirect from={`${this.props.match.path}`} to={`${this.props.match.path}/passed`} exact component={RecordList} />
        </Switch>
      </main>
    );
  }
}

export default Record;

本地效果為:D:\www\svn\project\react_redux\src\pages\record

<Switch>

只渲染出第一個與當前訪問地址匹配的 <Route> 或 <Redirect>

思考如下代碼,如果你訪問 /about,那么組件 About User Nomatch 都將被渲染出來,因為他們對應的路由與訪問的地址 /about 匹配。這顯然不是我們想要的,我們只想渲染出第一個匹配的路由就可以了,於是 <Switch> 應運而生!

<Route path="/about" component={About}/>
<Route path="/:user" component={User}/>
<Route component={NoMatch}/>

children: node
<Switch> 下的子節點只能是 <Route> 或 <Redirect> 元素。只有與當前訪問地址匹配的第一個子節點才會被渲染。<Route> 元素用它們的 path 屬性匹配,<Redirect> 元素使用它們的 from 屬性匹配。如果沒有對應的 path 或 from,那么它們將匹配任何當前訪問地址。

Switch詳細說明:http://blog.csdn.net/sinat_17775997/article/details/69218382

<Redirect>

<Redirect> 渲染時將導航到一個新地址,這個新地址覆蓋在訪問歷史信息里面的本該訪問的那個地址。

to: string
重定向的 URL 字符串

to: object
重定向的 location 對象

push: bool
若為真,重定向操作將會把新地址加入到訪問歷史記錄里面,並且無法回退到前面的頁面。

from: string
需要匹配的將要被重定向路徑。

Redirect詳細說明:http://blog.csdn.net/sinat_17775997/article/details/69218382

Prompt

對象和方法 history、location、match

比如從首頁進入到詳情頁得時候配合

<Route path="/detail/:kerwinId" render={props=>
          <Detail {...props} kerwin="OK"/>
      }>
      </Route>
render(){
        console.log(this.props)
}

詳情頁console.log得值

history:Object
  {
    action: "PUSH"  //string 路由跳轉到當前頁面執行的動作,分為 PUSH, REPLACE, POP
    length: 15    //number 瀏覽歷史堆棧中的條目數
    location: Object
    {
      hash: ""  //string URL的 hash 片段
      key: "um0f9t" 
      pathname: "/detail/3794"    //string URL路徑
      search: ""    // string URL中的查詢字符串
      state: undefined    //string 例如執行 push(path, state) 操作時,location 的 state 將被提供到堆棧信息里,state 只有在 browser 和 memory history 有效。
    }
    go:funciton go(n)   //將 history 堆棧中的指針向前移動 n
    goBack:function goBack()    //等同於 go(-1)
    goForward:function goForward()    //等同於 go(1)
    block:function block()   //阻止跳轉
    push:function push(path, state)  //在歷史堆棧信息里加入一個新條目。
    replace:function replace(path, state)  //在歷史堆棧信息里替換掉當前的條目
  }
kerwin: "ok"
location: Object
  {
     hash: ""
     key: "um0f9t"
     pathname: "/detail/3794"
     search: ""
     state: undefined
  }
match: Object
  {
     isExact: true   // bool 為 true 時,整個 URL 都需要匹配
     params: Object   //object 路徑參數,通過解析 URL 中的動態部分獲得鍵值對
     {
       kerwinId: "3794"
     }
     path: "/detail/:kerwinId"   //string 用來匹配的路徑模式,用於創建嵌套的 <Route>
     url: "/detail/3794"    //string URL 匹配的部分,用於嵌套的 <Link>
  }
staticContext: undefined

 

詳細說明在:http://blog.csdn.net/sinat_17775997/article/details/69218382

react-router4router搭配例子

import React from "react";
import ReactDOM from "react-dom";
import {
  BrowserRouter as Router,
  Route,
  Link,
  Redirect,
  Switch
} from 'react-router-dom'

import App from "./components/App/index"; 
import Home from "./components/Home/index"; 
import Cinema from "./components/Cinema/index"; 
import Me from "./components/Me/index"; 
import Card from "./components/Card/index"; 
import Film from "./components/Film/index"; 
import NowPlaying from "./components/NowPlaying/index"; 
import ComingSoon from "./components/ComingSoon/index"; 
import Detail from "./components/Detail/index"; 
const router = (
  <Router>
    <App>
      <Switch> {/*Renders the first child <Route> or <Redirect> that matches the location.*/}
      <Route path="/home" component={Home} />
      <Route path="/film" render={()=>
        <Film>
          <Switch>{/*Renders the first child <Route> or <Redirect> that matches the location.*/}
             <Route path="/film/now-playing" component={NowPlaying}/>
             <Route path="/film/coming-soon" component={ComingSoon}/>
             <Redirect from="/film" to="/film/now-playing"/> {/*重定向*/}
          </Switch>
        </Film>
      }>
      </Route>
      <Route path="/cinema" component={Cinema}>
      </Route>
      <Route path="/me" component={Me}>
      </Route>
      <Route path="/card" component={Card} >
      </Route>
      <Route path="/detail/:kerwinId" render={props=>
          <Detail {...props} kerwin="OK"/>
      }>
      </Route>
      <Redirect from="/" to="/home"/> {/*重定向*/}

      </Switch>
    </App>
  </Router>
) 

//export default router; 
ReactDOM.render(router,document.getElementById("box"));

本地效果查看為:http://localhost:8088/home

 

關於react route自從升級到4.1.1版本之后,直接

<Router history={browserHistory}></Router>

會報錯'react-router' does not contain an export named 'browserHistory'.,新版的估計不支持直接這樣使用(可憐我3.0的react route都可以),所以現在我們使用react route必須要重新進行配置。

請確保安裝一下模塊

"react": "^15.6.1", "react-dom": "^15.6.1", "react-router": "^4.1.1", "react-router-dom": "^4.1.1"

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM