react-router的簡單使用
React Router是一個基於React之上的強大路由庫,可以讓你嚮應用中快速的新增檢視和資料流,同時保持頁面與URL間的同步。
1.安裝:
npm install --save react-router
2.問題說明:
剛開始的時候由於沒有注意到版本資訊,導致出現了一些錯誤,現在記錄如下:
這是我package.js中的版本資訊,
說明1:react-router的2.x版本和4.x版本不相容,預設下載的4.x的版本,我這裡選擇的是2.x版本不然會報 “
TypeError: Cannot read property 'location' of undefined”
說明2:react 16和react-router2.x的版本不相容,會報“TypeError: Cannot read property 'func' of undefined”,我這裡講react降級到了15
3.路由配置:
(1)路由配置是一組指令,用來告訴router如何匹配URL
React.render((<Router> <Route path="/" component={App}> <Route path="about" component={About}> <Route path="inbox" component={Message}> </Route > </Router> ),doucument.body);
其中<Route>中指定路徑path 和 需要顯示的元件component相匹配,並且Route之間允許巢狀,如上:About元件的路徑就是“/about”。
(2)<IndexRoute>元件放在可以新增首頁效果 ,在還未點選about,或者inbox時,自動顯示在頁面上,即類似在當請求的的URL匹配某個目錄時,允許你指定一個類似index.html的入口檔案。
ReactDOM.render(
<Router>
<Route path="/" component={App}>
<IndexRoute component={DashBoard}/>
<Route path="about" component={About}/>
<Route path="inbox" component={Inbox}>
<Route path="message/:id" component={Message}/>
</Route>
</Route>
</Router>
, document.getElementById('root'));
顯示效果如下:
URL路徑與元件的聯絡如下:
如果在<Route>中將Message的路徑改為絕對路徑,如“/messages/:id”,
則最後一個URL與路徑的匹配改為:/messages/:id-》app->Inbox->Message
(3)上面一條的最後我們改了URL,這使得舊的URL會出現錯誤介面,這時,我們可以通過<Redirect>這個元件使得原來的URL也可以正常工作。
ReactDOM.render(
<Router>
<Route path="/" component={App}>
<IndexRoute component={DashBoard}/>
<Route path="about" component={About}/>
<Route path="inbox" component={Inbox}>
<Route path="/message/:id" component={Message}/>
<Redirect from="message/:id" to="/message/:id"/>
</Route>
</Route>
</Router>
, document.getElementById('root'));
(4)路由匹配的原理
三個屬性來決定是否匹配一個URL:
- 巢狀關係
巢狀路由被描述成一個樹形結構,並且通過深度優先遍歷尋找一個與給定URL相匹配的路由。
- 路徑語法
路由路徑是匹配一個(或一部分)URL 的 一個字元模式串。大部分的路由路徑都可以直接按照字面量理解,除了幾個特殊的符號:
:paramName
– 匹配一段位於 /
、?
或 #
之後的 URL。 命中的部分將被作為一個引數
()
– 在它內部的內容被認為是可選的
*
– 匹配任意字元(非貪婪的)直到命中下一個字元或者整個 URL 的末尾,並建立一 個 splat引數
- 優先順序
路由演算法會根據定義的順序自頂向下匹配路由。因此,當你擁有兩個兄弟路由節點配置時,你必須確認前一個路由不會匹配後一個路由中的路徑
4.Histories
React Router 是建立在 還是history之上的。 簡而言之,一個 history 知道如何去監聽瀏覽器位址列的變化, 並解析這個 URL 轉化為 location
物件, 然後 router 使用它匹配到路由,最後正確地渲染對應的元件。
(下面介紹一下history)
----------------------------------------分割線---------------------------------
history是一個JavaScript庫,它允許您在JavaScript執行的任何地方輕鬆管理會話歷史。history抽象了不同環境中的差異,並提供了一個最小的API,允許您管理歷史堆疊、導航、確認導航和會話之間的持久狀態。
history提供三種不同的方法去建立一個history物件,這取決於你的環境
createBrowserHistory,createMemoryHistory,createHashHistory
我們主要運用到createBrowserHistory,下面以這個為例子:
const history = createBrowserHistory(); const location = history.location; const unlisten = history.listen((location, action) => { console.log(location); }); history.push("/about",{some:"state"}); unlisten();
輸出的location物件為:
其中的pathname項就是當前url的地址。
有關history更多的資訊,可以參考:https://github.com/ReactTraining/history
-----------------------------又是一條分割線--------------------------------------------------------
在React Router中可以引入browserHistory
import { browserHistory } from 'react-router';
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={DashBoard}/>
<Route path="about" component={About}/>
<Route path="inbox" component={Inbox}>
<Route path="/message/:id" component={Message}/>
<Redirect from="message/:id" to="/message/:id"/>
</Route>
</Route>
</Router>
, document.getElementById('root'));
這樣位址列的地址會變為:
沒有了奇怪的/#/