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