React-Router4.0小結(jié)

react-router 還是 react-router-dom?

在 React 的使用中,我們一般要引入兩個(gè)包,react 和 react-dom,那么 react-router 和react-router-dom 是不是兩個(gè)都要引用呢?
非也,坑就在這里。他們兩個(gè)只要引用一個(gè)就行了,不同之處就是后者比前者多出了 <Link> <BrowserRouter> 這樣的 DOM 類組件。因此我們只需引用 react-router-dom 這個(gè)包就行了

react-router: 實(shí)現(xiàn)了路由的核心功能
react-router-dom: 基于react-router,加入了在瀏覽器運(yùn)行環(huán)境下的一些功能,例如:Link組件,會(huì)渲染一個(gè)a標(biāo)簽,Link組件源碼a標(biāo)簽行; BrowserRouterHashRouter組件,前者使用pushStatepopState事件構(gòu)建路由,后者使用window.location.hashhashchange事件構(gòu)建路由。

react-router-dom依賴react-router,所以我們使用npm安裝依賴的時(shí)候,只需要安裝相應(yīng)環(huán)境下的庫(kù)即可,不用再顯式安裝react-router。基于瀏覽器環(huán)境的開(kāi)發(fā),只需要安裝react-router-dom;npm會(huì)自動(dòng)解析react-router-dom包中package.json的依賴并安裝。
react-router-dom中package.json依賴:

"dependencies": {
    "history": "^4.7.2",
    "invariant": "^2.2.2",
    "loose-envify": "^1.3.1",
    "prop-types": "^15.5.4",
    "react-router": "^4.2.0",
    "warning": "^3.0.0"
  }

React-Router4.0不允許出現(xiàn)嵌套的子路由

例如:

<Router>
    <Route path="/" component={App}>
      <Route path="about" component={About} />
      <Route path="inbox" component={Inbox} />
    </Route>
  </Router>

React-Router4.0主張將路由拆分出來(lái),不直接使用嵌套路由
源文件改為

<BrowserRouter>
    <Route path="/" component={App}></Route>
</BrowserRouter>

然后在APP組件里面再次寫(xiě)入

<Switch>
  <Route path="about" component={About} />
  <Route path="inbox" component={Inbox} />
<Switch>

只渲染第一個(gè)匹配的組件<Switch>: 一個(gè)路由可能同時(shí)匹配多個(gè)路徑,在<Switch>中,只渲染匹配的第一個(gè),其他的放棄。之前這是Router的默認(rèn)行為,4.0中不默認(rèn)了

在react-router 2.0中可選參數(shù)是這樣寫(xiě)的

<Route path='/index(/:hello)' />

而在react-4.0中你會(huì)驚喜的發(fā)現(xiàn)這種寫(xiě)法沒(méi)用了

要寫(xiě)成這樣

<Route path='/index/:hello?' />

后邊的問(wèn)號(hào)表示這個(gè)參數(shù)是可選的

Router變化

react-router將history分為三類。

  • hashHistory 老版本瀏覽器的history
  • browserHistory h5的history
  • createMemoryHistory node環(huán)境下的history,存儲(chǔ)在memory中

4.0之前版本的react-router針對(duì)三者分別實(shí)現(xiàn)了createHashHistory、createBrowserHistory和create MemoryHistory三個(gè)方法來(lái)創(chuàng)建三種情況下的history,這里就不討論他們不同的處理方式了,好奇的可以去了解一下~
到了4.0版本,在react-router-dom中直接將這三種history作了內(nèi)置,于是我們看到了BrowserRouter、HashRouter、MemoryRouter這三種Router,當(dāng)然,你依然可以使用React-router中的Router,然后自己通過(guò)createHistory來(lái)創(chuàng)建history來(lái)傳入。

Route標(biāo)簽

它最基本的職責(zé)就是當(dāng)頁(yè)面的訪問(wèn)地址與 Route 上的 path 匹配時(shí),就渲染出對(duì)應(yīng)的 UI 界面。
<Route> 自帶三個(gè) render method 和三個(gè) props 。
render methods 分別是:

  • <Route component>
  • <Route render>
  • <Route children>

每種 render method 都有不同的應(yīng)用場(chǎng)景,同一個(gè)<Route> 應(yīng)該只使用一種 render method ,大部分情況下你將使用 component 。

props 分別是:

  • match
  • location
  • history

location對(duì)象包括:

  • pathname 同window.location.pathname
  • search 同window.location.search
  • state 一個(gè)捆綁在這個(gè)地址上的object對(duì)象
  • action PUSH, REPLACE, 或者 POP中的一個(gè)
  • key 唯一ID

發(fā)現(xiàn) location.query屬性沒(méi)有了,現(xiàn)在通過(guò) 'query-string' 模塊進(jìn)行轉(zhuǎn)換獲取
import queryString from 'query-string'
let query=this.query=queryString.parse(location.search);
match 對(duì)象包含了 <Route path> 如何與 URL 匹配的信息,具有以下屬性:

match對(duì)象包括:

  • params: object 路徑參數(shù),通過(guò)解析 URL 中的動(dòng)態(tài)部分獲得鍵值對(duì)
  • isExact: bool 為 true 時(shí),整個(gè) URL 都需要匹配
  • path: string 用來(lái)匹配的路徑模式,用于創(chuàng)建嵌套的 <Route>
  • url: string URL 匹配的部分,用于嵌套的 <Link>

存: this.props.history.push({pathname:"/web/updateStaff/" + text.userId});
讀:this.props.match.params.userId

想了解更詳細(xì)的參數(shù)傳遞,可以參考 http://www.itdecent.cn/p/ad8cc02b9e6c

BrowserRouter和HashRouter區(qū)別

hashHistory使用 URL 中的 hash(#)部分去創(chuàng)建路由,舉例來(lái)說(shuō),用戶訪問(wèn)http://www.example.com/,實(shí)際會(huì)看到的是http://www.example.com/#/

當(dāng)頁(yè)面刷新的時(shí)候,對(duì)于BrowserHistory, 瀏覽器會(huì)向后臺(tái)發(fā)送整個(gè)URL的請(qǐng)求, 而對(duì)于HashHistory, 它只會(huì)請(qǐng)求后臺(tái)的根目錄。

browserHistory 是使用 React-Router 的應(yīng)用推薦的 history方案。它使用瀏覽器中的 History API 用于處理 URL,創(chuàng)建一個(gè)像example.com/list/123這樣真實(shí)的 URL 。
在browserHistory 模式下,URL 是指向真實(shí) URL 的資源路徑,當(dāng)通過(guò)真實(shí) URL 訪問(wèn)網(wǎng)站的時(shí)候,由于路徑是指向服務(wù)器的真實(shí)路徑,但該路徑下并沒(méi)有相關(guān)資源,所以用戶訪問(wèn)的資源不存在。
當(dāng)本地使用browserHistory , 因?yàn)閣ebpack.config.js中使用 webpack-dev-server 已經(jīng)做了配置。所以不會(huì)出現(xiàn)刷新頁(yè)面404.

webpackConfig.devServer = {
        contentBase: path.resolve(__dirname, 'build'),
        compress: true, //gzip壓縮
        historyApiFallback: true,
    };

但是要想在發(fā)版后正常使用,服務(wù)器需要進(jìn)行相關(guān)路由配置,參考 (這里):

問(wèn)題解決

1.使用render加載組件后,組件加載不出來(lái)

https://blog.csdn.net/aqtata/article/details/76169974

2.為什么用 this.props.history.push({......})不起作用

用此方法不起作用說(shuō)明,你直接引用的Router路由,在ReactRouter4.x里Router里面并沒(méi)有內(nèi)置history對(duì)象,React Router 是建立在 history 之上的。 簡(jiǎn)而言之,一個(gè) history 知道如何去監(jiān)聽(tīng)瀏覽器地址欄的變化, 并解析這個(gè) URL 轉(zhuǎn)化為 location 對(duì)象, 然后 router 使用它匹配到路由,最后正確地渲染對(duì)應(yīng)的組件。所以你只能通過(guò)createHistory創(chuàng)建的自定義的history對(duì)象,并將其傳入Router傳入來(lái)實(shí)現(xiàn)路由動(dòng)態(tài)跳轉(zhuǎn)

// HTML5 history, 推薦
import createHistory from 'history/lib/createBrowserHistory'

// Hash history
import createHistory from 'history/lib/createHashHistory'

// 內(nèi)存 history (如:node環(huán)境)
import createHistory from 'history/lib/createMemoryHistory'
const history = createHistory()
......
<Router history={history }></Router>

history 一個(gè)管理js應(yīng)用session會(huì)話歷史的js庫(kù)。它將不同環(huán)境(瀏覽器,node...)的變量統(tǒng)一成了一個(gè)簡(jiǎn)易的API來(lái)管理歷史堆棧、導(dǎo)航、確認(rèn)跳轉(zhuǎn)、以及sessions間的持續(xù)狀態(tài)。

3.為什么使用IndexRoute會(huì)報(bào)錯(cuò)

因?yàn)閞eact-router4*已經(jīng)拋棄了IndexRoute
以前

<BrowserRouter>
   <Route path="/" component={Frame}>
        <IndexRoute component={Home} />
        <Route path="/detail" component={Detail}></Route>      
    </Route>
 </BrowserRouter>

現(xiàn)在的默認(rèn)路由為

<BrowserRouter>
    <Frame>             
       <Route path="/" exact component={Home}/>
       <Route path="/detail" component={Detail}></Route>         
     </Frame>
  </BrowserRouter>     
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • React Router 4.0 (以下簡(jiǎn)稱 RR4) 已經(jīng)正式發(fā)布,它遵循React的設(shè)計(jì)理念,即萬(wàn)物皆組件。所...
    梁相輝閱讀 98,053評(píng)論 24 195
  • React-Router v4 1. 設(shè)計(jì)理念1.1. 動(dòng)態(tài)路由1.2. 嵌套路由1.3. 響應(yīng)式路由 2. 快速...
    wlszouc閱讀 8,715評(píng)論 0 14
  • 一、基本用法 React Router 安裝命令如下。 $ npm install -S react-router...
    sunnyghx閱讀 4,596評(píng)論 0 6
  • 世界上最痛苦的事兒不是人活著錢(qián)沒(méi)了 而是被催婚 寸姐也被催過(guò)婚 坦白講這種痛苦旁人真的很難理解 當(dāng)老一輩人用老思想...
    半點(diǎn)分寸閱讀 734評(píng)論 0 0
  • 剎那 緣起 其實(shí)這個(gè)問(wèn)題,本身就是回答! 閑賦在家一段時(shí)間,看了一堆書(shū)后,正準(zhǔn)備寫(xiě)點(diǎn)東西時(shí),通過(guò)簡(jiǎn)書(shū)的小丸子,知道...
    木子?xùn)V閱讀 331評(píng)論 9 5

友情鏈接更多精彩內(nèi)容