React Router是一個基於React之上的強大路由庫,可以讓你嚮應用中快速的添加視圖和數據流,同時保持頁面與URL間的同步。 1.安裝: 2.問題說明: 剛開始的時候由於沒有註意到版本信息,導致出現了一些錯誤,現在記錄如下: 這是我package.js中的版本信息, 說明1:react-ro ...
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'));
這樣地址欄的地址會變為:
沒有了奇怪的/#/