前面的话
路由用来分发请求。后端是提供服务的,所以它的路由是在找controller,前端是显示页面的,所以它的路由是在找component。本文将详细介绍react-router-dom的内容
Router
Router是路由器组件的低阶接口,通常会使用如下某个高阶router来替代它
<BrowserRouter> <HashRouter> <MemoryRouter> <NativeRouter> <StaticRouter>
【BrowserRouter】
最常用的是BrowserRouter
import { BrowserRouter } from ‘react-router-dom‘ <BrowserRouter basename={optionalString} forceRefresh={optionalBool} getUserConfirmation={optionalFunc} keyLength={optionalNumber} > <App/> </BrowserRouter>
1、basename: 当前位置的基准 URL。如果页面部署在服务器的二级(子)目录,需要将 basename 设置到此子目录。 正确的 URL 格式是前面有一个前导斜杠,但不能有尾部斜杠
<BrowserRouter basename="/calendar"/>
2、getUserConfirmation:当导航需要确认时执行的函数。默认使用 window.confirm
// 使用默认的确认函数 const getConfirmation = (message, callback) => { const allowTransition = window.confirm(message) callback(allowTransition) } <BrowserRouter getUserConfirmation={getConfirmation}/>
3、forceRefresh:当设置为 true 时,在导航的过程中整个页面将会刷新。 只有当浏览器不支持 html5 的 history API 时,才设置为 true
const supportsHistory = ‘pushState‘ in window.history <BrowserRouter forceRefresh={!supportsHistory}/>
4、keyLength:location.key 的长度。默认是 6
<BrowserRouter keyLength={12}/>
5、BrowserRouter只能渲染单一子元素
Route
Route是react-router中最重要的组件,用来匹配请求并渲染相应组件
1、path 路径的匹配值,可以包括以下几种特殊符号
:paramName – 匹配一段位于 /、? 或 # 之后的 URL。 命中的部分将被作为一个参数
() – 在它内部的内容被认为是可选的
* – 匹配任意字符(非贪婪的)直到命中下一个字符或者整个 URL 的末尾,并创建一个 splat 参数
例子如下所示:
<Route path="/hello/:name"> // 匹配 /hello/michael 和 /hello/ryan <Route path="/hello(/:name)"> // 匹配 /hello, /hello/michael 和 /hello/ryan <Route path="/files/*.*"> // 匹配 /files/hello.jpg 和 /files/path/to/hello.jpg
2、component 要显示的组件
import { BrowserRouter as Router, Route } from ‘react-router-dom‘ <Router> <div> <Route exact path="/" component={Home}/> <Route path="/news" component={NewsFeed}/> </div> </Router>
3、render 函数中return的值就是要显示的内容
<Route path="/home" render={() => <div>Home</div>}/>
4、children 与render的区别在于,不管有没有匹配,都想显示的内容
const ListItemLink = ({ to, ...rest }) => ( <Route path={to} children={({ match }) => ( <li className={match ? ‘active‘ : ‘‘}> <Link to={to} {...rest}/> </li> )}/> )
[注意]component/render/children只能三个选一个使用
【匹配规则】
默认地,路由进行宽松匹配。在下面例子中,路由匹配到/one时,既显示组件A,也显示组件B
<Route path="/one" component={A}/> <Route path="/one/two" component={B}/>
如果要进行确切匹配,则需要添加exact属性。这样,路由匹配到/one时,只显示组件A
<Route exact path="/one" component={A}/> <Route path="/one/two" component={B}/>
还有一种是严格匹配,即斜杠也必须严格匹配。下面例子中,路由匹配到/one/时,会显示组件A,但匹配到/one时,什么都不会显示
<Route strict path="/one/" component={A}/>
[注意]严格匹配并不是确切匹配。下面例子中,路由匹配到/one时,即显示组件A,也显示组件B
<Route strict path="/one" component={A}/> <Route path="/one/two" component={B}/>
如果要确切匹配,则需要
<Route exact strict path="/one" component={A}/>
但是,一般地,strict属性很少使用
【属性】
Route默认携带三个props:包括match、location、history
如果使用component,则使用this.props来获取,如果是render,则在回调函数中使用参数(props)=>{}来获取
1、match
match包括以下属性
params 键值对 isExact 是否确切匹配 path 路径中设置的值 url URL中的path值
2、location
location中包含如下属性
[注意]直接访问location,而不是访问history.location
{ key: ‘ac3df4‘, // not with HashHistory! pathname: ‘/somewhere‘ search: ‘?some=search-string‘, hash: ‘#howdy‘, state: { [userDefined]: true } }
通过Link传递的state,可以在location中获取到
[注意]刚开始时,或者直接刷新浏览器,state是没有值的,只有跳转到该链接时,state才有值。再后来,刷新也有值了
3、history
history包含如下属性
length: history栈的长度
action: 当前的action
location: 当前的location对象
history包含如下方法
push() goBack() = go(-1) goForward() = go(1) go() 跳转到 history栈中的哪个enter replace(path, [state]) 替换history栈中的当前entry push(path, [state]) 添加当前entry到history栈中
Redirect
Redirect将页面导航到新位置,新位置将覆盖history栈中的当前位置,类似于服务器端的重定向(HTTP 3xx)
to属性可以是一个字符串,表示跳转的地址
<Route exact path="/" render={() => ( loggedIn ? ( <Redirect to="/dashboard"/> ) : ( <PublicHomePage/> ) )}/>
to属性也可以是一个对象
<Redirect to={{ pathname: ‘/login‘, search: ‘?utm=your+face‘, state: { referrer: currentLocation } }}/>
push属性为true时,表示添加新记录到history栈中,而不是替换当前记录
<Redirect push to="/somewhere/else"/>
Link
Link是对a标签的封装,提供无刷新的页面跳转。Link标签主要的属性是to属性
1、一般地,to是一个字符串
<Link to="/about">关于</Link>
2、也可以写成对象的形式
<Link to={{ pathname: ‘/courses‘, search: ‘?sort=name‘, hash: ‘#the-hash‘, state: { fromDashboard: true } }}/>
[注意]在Link里的子组件或同组件的点击事件,最好加上阻止默认行为和阻止冒泡
<Link> <div onclick={}></div> </Link> <Link onclick={}>
【NavLink】
NavLink相对于Link来说,增加了一些样式属性
activeClassName表示被匹配的a标签的样式名;activeStyle表示被匹配的a标签的样式
<NavLink to="/faq" activeClassName="selected" >FAQs</NavLink>
<NavLink to="/faq" activeStyle={{ fontWeight: ‘bold‘, color: ‘red‘ }} >FAQs</NavLink>
Switch
渲染Route或Redirect匹配到的第一个子元素
<Switch> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> <Route path="/:user" component={User}/> <Route component={NoMatch}/> </Switch>
[注意]switch必须直接包括Route,中间不可包含div,否则不生效