山地狐水中鱼 發表於 2019-9-24 08:10:00

react-router-dom中link与Navlink

<p>React Router 是一个基于&nbsp;React&nbsp;之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 URL 间的同步。</p>
<p>目前react-router最新版本已经到4.0+,因为新的版本是一次非常大的改动,所以这里直接讨论4.0以上版本。</p>
<h2>引用</h2>
<div class="cnblogs_code">
<pre>react-router        // React Router 核心
react-router-dom     // 用于 DOM 绑定的 React Router
react-router-native   // 用于 React Native 的 React Router
react-router-redux   // React Router 和 Redux 的集成
react-router-config    // 静态路由配置的小助手</pre>
</div>
<p>以上资源库按需引用,本文讨论web端应用,只需要引用react-router-dom即可。(如果需要搭配redux则还需引用react-router-redux)</p>
<h2>主要组件</h2>
<h2>&lt;Route&gt;</h2>
<p>Route组件主要的作用就是当一个location匹配路由的path时,渲染某些UI,exp:</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre> 1 import { BrowserRouter as Router, Route } from 'react-router-dom'
2
3 &lt;Router&gt;
4   &lt;div&gt;
5   &lt;Route exact path="/" component={Home}/&gt;
6   &lt;Route path="/news" component={NewsFeed}/&gt;
7   &lt;/div&gt;
8 &lt;/Router&gt;
9 // If the location of the app is / then the UI hierarchy will be something like:
10
11 &lt;div&gt;
12   &lt;Home/&gt;
13   &lt;!-- react-empty: 2 --&gt;
14 &lt;/div&gt;
15 // And if the location of the app is /news then the UI hierarchy will be:
16
17 &lt;div&gt;
18   &lt;!-- react-empty: 1 --&gt;
19   &lt;NewsFeed/&gt;
20 &lt;/div&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<p>&lt;Route&gt; 的三种渲染方式 :</p>
<div class="cnblogs_code">
<pre>&lt;Route component&gt;  // 只有当访问地址和路由匹配时,一个 React component 才会被渲染,此时此组件接受 route props (match, location, history)
&lt;Route render&gt;    // 此方法适用于内联渲染,不会引起意料之外的重新挂载
&lt;Route children&gt;   // 不管地址匹配与否都会被调用,与render的工作方式基本一样</pre>
</div>
<p>tips:同一个&lt;Route&gt;中只使用一种渲染方式,多种会被覆盖,优先级为component&gt;render&gt;children。</p>
<p>&nbsp;</p>
<p>&lt;Route&gt; 的三个属性:</p>
<div class="cnblogs_code">
<pre>path(string):   // 路由匹配路径。(没有path属性的Route 总是会 匹配);
exact(bool):   // 为true时,则要求路径与location.pathname必须完全匹配;
strict(bool):  // 为true时,有结尾斜线的路径只能匹配有斜线的location.pathname</pre>
</div>
<p>&nbsp;</p>
<h2>&lt;BrowserRouter&gt;</h2>
<p><code>&lt;Router&gt;</code>&nbsp;使用 HTML5 提供的 history API (<code>pushState</code>,&nbsp;<code>replaceState</code>&nbsp;和&nbsp;<code>popstate</code>&nbsp;事件) 来保持 UI 和 URL 的同步。</p>
<p><strong>属性:</strong></p>
<p>basename: string</p>
<p>作用:为所有位置添加一个基准URL(假如你需要把页面部署到服务器的二级目录,你可以使用&nbsp;<code>basename</code>&nbsp;设置到此目录)</p>
<div class="cnblogs_code">
<pre>&lt;BrowserRouter basename="/minooo" /&gt;
&lt;Link to="/react" /&gt;   // 最终渲染为 &lt;a href="/minooo/react"&gt;</pre>
</div>
<p>&nbsp;</p>
<p>getUserConfirmation: func<br>作用:导航到此页面前执行的函数,默认使用 window.confirm</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>const getConfirmation = (message, callback) =&gt; {
const allowTransition = window.confirm(message)
callback(allowTransition)
}

&lt;BrowserRouter getUserConfirmation={getConfirmation('Are you sure?', yourCallBack)} /&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<p>forceRefresh: bool<br>作用:当浏览器不支持 HTML5 的 history API 时强制刷新页面。</p>
<div class="cnblogs_code">
<pre>const supportsHistory = 'pushState' in window.history
&lt;BrowserRouter forceRefresh={!supportsHistory} /&gt;</pre>
</div>
<p>&nbsp;</p>
<p>keyLength: number<br>作用:设置它里面路由的&nbsp;<code>location.key</code>&nbsp;的长度。默认是6。(key的作用:点击同一个链接时,每次该路由下的&nbsp;<code>location.key</code>都会改变,可以通过 key 的变化来刷新页面。)</p>
<div class="cnblogs_code">
<pre>&lt;BrowserRouter keyLength={12} /&gt;</pre>
</div>
<p>&nbsp;</p>
<p>children: node<br>作用:渲染单一子元素。<br><br></p>
<h2>&lt;Link&gt;</h2>
<p>为应用提供声明式的、无障碍导航。</p>
<div class="cnblogs_code">
<pre>import { Link } from 'react-router-dom'

&lt;Link to="/about"&gt;关于&lt;/Link&gt;</pre>
</div>
<h3>属性:</h3>
<h4 id="Link-to-string">to: string</h4>
<p>需要跳转到的路径(pathname)或地址(location)。</p>
<div class="cnblogs_code">
<pre>&lt;Link to="/courses"/&gt;</pre>
</div>
<h4>&nbsp;</h4>
<h4 id="Link-to-object">to: object</h4>
<p>需要跳转到的地址(location)。</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>&lt;Link to={{
pathname: '/courses',
search: '?sort=name',
hash: '#the-hash',
state: { fromDashboard: true }
}}/&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<h4 id="Link-replace-bool">replace: bool</h4>
<p>当设置为&nbsp;<code>true</code>&nbsp;时,点击链接后将使用新地址替换掉访问历史记录里面的原地址。</p>
<p>当设置为&nbsp;<code>false</code>&nbsp;时,点击链接后将在原有访问历史记录的基础上添加一个新的纪录。</p>
<p>默认为&nbsp;<code>false</code>。</p>
<p>&nbsp;</p>
<h2>&lt;NavLink&gt;</h2>
<p><code>&lt;NavLink&gt;</code>是<code>&lt;Link&gt;</code>&nbsp;的一个特定版本, 会在匹配上当前 URL 的时候会给已经渲染的元素添加样式参数</p>
<h3>属性</h3>
<h4>activeClassName: string</h4>
<p>导航选中激活时候应用的样式名,默认样式名为&nbsp;<code>active</code></p>
<div class="cnblogs_code">
<pre>&lt;NavLink
to="/about"
activeClassName="selected"
&gt;MyBlog&lt;/NavLink&gt;</pre>
</div>
<p>&nbsp;</p>
<h4>activeStyle: object</h4>
<p>如果不想使用样式名就直接写style</p>
<div class="cnblogs_code">
<pre>&lt;NavLink
to="/about"
activeStyle={{ color: 'green', fontWeight: 'bold' }}
&gt;MyBlog&lt;/NavLink&gt;</pre>
</div>
<p>&nbsp;</p>
<h4>exact: bool</h4>
<p>若为 true,只有当访问地址严格匹配时激活样式才会应用</p>
<h4>strict: bool</h4>
<p>若为 true,只有当访问地址后缀斜杠严格匹配(有或无)时激活样式才会应用</p>
<h4>isActive: func</h4>
<p>决定导航是否激活,或者在导航激活时候做点别的事情。不管怎样,它不能决定对应页面是否可以渲染。</p>
<h2>&lt;Switch&gt;</h2>
<p>只渲染出第一个与当前访问地址匹配的&nbsp;<code>&lt;Route&gt;</code>&nbsp;若没有匹配则渲染&nbsp;<code>&lt;Redirect&gt;</code></p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>import { Switch, Route } from 'react-router'

&lt;Switch&gt;
&lt;Route exact path="/" component={Home}/&gt;
&lt;Route path="/about" component={About}/&gt;
&lt;Route path="/:user" component={User}/&gt;
&lt;Redirect to={NoMatch}/&gt;
&lt;/Switch&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<h2>&lt;Redirect&gt;</h2>
<p><code>&lt;Redirect&gt;</code>&nbsp;渲染时将导航到一个新地址,这个新地址覆盖在访问历史信息里面的本该访问的那个地址。</p>
<h3>属性</h3>
<h4>to: string</h4>
<p>重定向的 URL 字符串</p>
<h4>to: object</h4>
<p>重定向的 location 对象</p>
<h4>push: bool</h4>
<p>若为真,重定向操作将会把新地址加入到访问历史记录里面,并且无法回退到前面的页面。</p>
<h4>from: string</h4>
<p>需要匹配的将要被重定向路径。</p>
<p>&nbsp;</p>
<h2>&lt;Prompt&gt;</h2>
<p>当用户离开当前页面前做出一些提示。</p>
<h3>属性</h3>
<h4>message: string</h4>
<p>当用户离开当前页面时,设置的提示信息。</p>
<div class="cnblogs_code">
<pre>&lt;Prompt message="确定要离开?" /&gt;</pre>
</div>
<p>&nbsp;</p>
<h4>message: func</h4>
<p>当用户离开当前页面时,设置的回掉函数</p>
<div class="cnblogs_code">
<pre>&lt;Prompt message={location =&gt; (
`Are you sue you want to go to ${location.pathname}?`
)} /&gt;</pre>
</div>
<p>&nbsp;</p>
<h4>when: bool</h4>
<p>通过设置一定条件要决定是否启用 Prompt</p>
<p>&nbsp;</p>
<h2>对象和方法</h2>
<h3>history</h3>
<p>history 对象通常具有以下属性和方法:</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>length: number      // 浏览历史堆栈中的条目数
action: string      // 路由跳转到当前页面执行的动作,分为 PUSH, REPLACE, POP
location: object       // 当前访问地址信息组成的对象,具有如下属性:
pathname: string       // URL路径
search: string         // URL中的查询字符串
hash: string         // URL的 hash 片段
state: string          // 例如执行 push(path, state) 操作时,location 的 state 将被提供到堆栈信息里,state 只有在 browser 和 memory history 有效。
push(path, )    // 在历史堆栈信息里加入一个新条目。
replace(path, ) // 在历史堆栈信息里替换掉当前的条目
go(n)                  // 将 history 堆栈中的指针向前移动 n。
goBack()               // 等同于 go(-1)
goForward            // 等同于 go(1)
block(prompt)          // 阻止跳转</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>history 对象是可变的,因此建议从&nbsp;<code>&lt;Route&gt;</code>&nbsp;的 prop 里来获取 location,而不是从 history.location 直接获取。这样可以保证 React 在生命周期中的钩子函数正常执行,exg:</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>class Comp extends React.Component {
componentWillReceiveProps(nextProps) {
    // locationChanged
    const locationChanged = nextProps.location !== this.props.location

    // 错误方式,locationChanged 永远为 false,因为history 是可变的
    const locationChanged = nextProps.history.location !== this.props.history.location
}
}</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<h3>&nbsp;</h3>
<h3>location</h3>
<p>location 是指你当前的位置,将要去的位置,或是之前所在的位置</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>{
key: 'sdfad1'
pathname: '/about',
search: '?name=cz'
hash: '#af01a',
state: {
    price: 998
}
}</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<p>在以下情境中可以获取 location 对象</p>
<div class="cnblogs_code">
<pre>在 Route component 中,以 this.props.location 获取
在 Route render 中,以 ({location}) =&gt; () 方式获取
在 Route children 中,以 ({location}) =&gt; () 方式获取
在 withRouter 中,以 this.props.location 的方式获取</pre>
</div>
<p>&nbsp;</p>
<p>location 对象不会发生改变,因此可以在生命周期的回调函数中使用 location 对象来查看当前页面的访问地址是否发生改变。这种技巧在获取远程数据以及使用动画时非常有用</p>
<div class="cnblogs_code">
<pre>componentWillReceiveProps(nextProps) {
if (nextProps.location !== this.props.location) {
    // 已经跳转了!
}
}</pre>
</div>
<p>&nbsp;</p>
<p>可以在不同情境中使用 location:</p>
<div class="cnblogs_code">
<pre>&lt;Link to={location} /&gt;
&lt;NaviveLink to={location} /&gt;
&lt;Redirect to={location /&gt;
history.push(location)
history.replace(location)</pre>
</div>
<p>&nbsp;</p>
<h3>match</h3>
<p>match 对象包含了 &lt;Route path&gt; 如何与 URL 匹配的信息,具有以下属性:</p>
<div class="cnblogs_code">
<pre>params: object   // 路径参数,通过解析 URL 中的动态部分获得键值对
isExact: bool    // 为 true 时,整个 URL 都需要匹配
path: string   // 用来匹配的路径模式,用于创建嵌套的 &lt;Route&gt;
url: string      // URL 匹配的部分,用于嵌套的 &lt;Link&gt;</pre>
</div>
<p>&nbsp;</p>
<p>获取 match 对象</p>
<div class="cnblogs_code">
<pre>在 Route component 中,以 this.props.match获取
在 Route render 中,以 ({match}) =&gt; () 方式获取
在 Route children 中,以 ({match}) =&gt; () 方式获取
在 withRouter 中,以 this.props.match的方式获取matchPath 的返回值</pre>
</div><br><br>
来源:https://www.cnblogs.com/qinlinkun/p/11576205.html
頁: [1]
查看完整版本: react-router-dom中link与Navlink