react router4 官網中文文檔地址:https://react-router.docschina.org
下載包:
npm install react-router-dom --save
文檔原文:在web應用程序中使用的所有組件都應該從react-router-dom中取
react-router應用程序的核心應該是一個router組件,對於web項目,react-router-dom提供了<BrowserRouter>和<HashRouter>路由。這兩個路由都會爲你創建一個專門的history對象。一般來說,如果你有一個相應請求的服務器,則你應該使用<BrowserRouter>,如果你使用的是靜態文件的服務器,則應該使用<BrowserRouter>。
文檔中還提到了一個<MemoryRouter>,文檔原文:<Router>能在內存中保存你的URL的歷史記錄(並不會對地址欄進行讀寫)。很適合在測試環境和非瀏覽器環境中使用,例如ReactNative。
我嘗試直接用<Router>...</Router>時提示錯誤,history是必須的
Warning: Failed prop type: The prop `history` is marked as required in `Router`, but its value is `undefined`.
in Router (created by App)
in App
由於BrowserRouter需要服務端配置,所以項目裏使用的是HashRouter。
之前的版本中使用hash history的寫法是:
import createHistory from 'history/createHashHistory'
const history = createHistory()
<Router history={history}></Route>
當我直接在router下寫多個一個route時,瀏覽器報錯:應該只有一個子元素
A <Router> may have only one child element
文檔原文:路由匹配是通過比較<Route>的path屬性和當前地址的pathname來實現的。當一個<Route>匹配成功,它將渲染其內容,當不匹配就會渲染null。而沒有path的Router將始終被匹配.<Switch>會遍歷其所有的子<Route>元素,並僅渲染與當前路徑匹配的第一個元素。
所以可以用沒有path的匹配404錯誤組件。
App.js
import React, {Component} from 'react';
import { HashRouter,Router,Route,Switch} from 'react-router-dom';
import AddUser from './AddUser';
import User from './User';
import UserList from './UserList';
import Exception404 from './404';
export default class App extends Component {
render() {
return (
<HashRouter>
<Switch>
<Route path="/" component={AddUser} exact/>>
<Route path="/user" component={User} />
<Route path="/userlist" component={UserList} />
<Route component={Exception404} />
</Switch>
</HashRouter>
)
}
}
中間遇到一個問題,當我這樣設置路由
<HashRouter>
<Route path="/" component={AddUser} exact>
<Route path="/user" component={User} />
<Route path="/userlist" component={UserList} />
</Route>
</HashRouter>
瀏覽器控制檯警告:
Warning: You should not use <Route component> and <Route children> in the same route; <Route children> will be ignored
嵌套路由不能寫在同一個route中了,子組件會被忽略,改爲:
<HashRouter>
<Switch>
<Route path="/" component={AddUser} exact/>
<Route path="/user" component={User} />
<Route path="/userlist" component={UserList} />
<Route component={Exception404} />
</Switch>
</HashRouter>
在使用HashRouter過程中,遇到一個問題:當連續跳轉到同一個路徑,會報錯:
Warning: Hash history cannot PUSH the same path; a new entry will not be added to the history stack
翻譯過來就是使用Hash這種history時不能兩次添加相同的路徑,在網上看到一個帖子解決了這個問題,兩種方法:第一種使用Link的replace屬性:如果爲true,則單擊鏈接將替換歷史堆棧中的當前入口,而不是添加新入口;第二種是這個問題只在開發環境存在而生產環境正常,所以將模式設置爲生產環境即可,原文鏈接:https://www.cnblogs.com/ostrich-sunshine/p/9770774.html
不小心踩到的另一個小坑,就是寫Route時剛開始沒有寫exact,導致無論點擊哪個Link,頁面始終是AddUser組件的頁面,
文檔原文:exact:bool 如果爲true,則只有在路徑完全匹配location.pathname時才匹配。
以上邊爲例:path:"/"
exact==false, /匹配, /user 匹配 ,/userlist匹配,/add/user匹配。。
exact==true, /匹配,/user 不匹配,/*不匹配。。
另一個相似的Route屬性是strict,表示:文檔原文:如果爲真,當真實的路徑具有一個斜線將只匹配一個斜線location.pathname,如果有更多的URL段location.pathname,將不起作用。
舉例:path:'/one/'
strict==true, /one 不匹配,/one/ 匹配 ,/one/two 不匹配
文檔原文:可以使用strict來強制執行location.pathname沒有結尾斜槓,但爲了執行此操作,strict和exact必須都是true
舉例格式:path路徑-是否匹配-location.pathname
/one yes /one
/one no /one/
/one no /one/two