React-router5.x使用总结
<p>在 React router 中通常使用的组件有三种:</p><ul>
<li>路由组件(作为根组件): BrowserRouter(history模式) 和 HashRouter(hash模式)</li>
<li>路径匹配组件: Route 和 Switch</li>
<li>导航组件: Link 和 NavLink</li>
</ul>
<p>关于路由组件,如果我们的应用有服务器响应web的请求,建议使用<BrowserRouter>组件; 如果使用静态文件服务器,建议使用<HashRouter>组件。</p>
<h3>1、安装:</h3>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="27">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;cnpm i react-router react-router-dom -S&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs">cnpm i react-router react-router-dom -S</code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<h3>2、使用:</h3>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="26">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;import React, { Component } from 'react'\nimport { BrowserRouter, Route, Link } from 'react-router-dom'\nimport ThisCollapse from '@/components/ThisCollapse'\nimport ThisProgress from '@/components/ThisProgress'\nimport ThisTable from '@/components/ThisTable'\n\nexport default class App extends Component {\n render() {\n return (\n &lt;BrowserRouter&gt;\n &lt;div&gt;\n &lt;Route path=\&quot;/\&quot; exactcomponent={ThisTable}&gt;&lt;/Route&gt;\n &lt;Route path=\&quot;/a\&quot; exactcomponent={ThisCollapse} &gt;&lt;/Route&gt;\n &lt;Route path=\&quot;/b\&quot; exactcomponent={ThisProgress} &gt;&lt;/Route&gt;\n &lt;/div&gt;\n &lt;/BrowserRouter&gt;\n )\n }\n}\n&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><span class="hljs-keyword">import React, { Component } <span class="hljs-keyword">from <span class="hljs-string">'react'
<span class="hljs-keyword">import { BrowserRouter, Route, Link } <span class="hljs-keyword">from <span class="hljs-string">'react-router-dom'
<span class="hljs-keyword">import ThisCollapse <span class="hljs-keyword">from <span class="hljs-string">'@/components/ThisCollapse'
<span class="hljs-keyword">import ThisProgress <span class="hljs-keyword">from <span class="hljs-string">'@/components/ThisProgress'
<span class="hljs-keyword">import ThisTable <span class="hljs-keyword">from <span class="hljs-string">'@/components/ThisTable'
<span class="hljs-keyword">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Component {
render() {
<span class="hljs-keyword">return (
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">BrowserRouter>
<span class="hljs-tag"><<span class="hljs-name">div>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/" <span class="hljs-attr">exact<span class="hljs-attr">component=<span class="hljs-string">{ThisTable}><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/a" <span class="hljs-attr">exact<span class="hljs-attr">component=<span class="hljs-string">{ThisCollapse} ><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/b" <span class="hljs-attr">exact<span class="hljs-attr">component=<span class="hljs-string">{ThisProgress} ><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"></<span class="hljs-name">div>
<span class="hljs-tag"></<span class="hljs-name">BrowserRouter>
)
}
}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<h3>3、路由组件 BrowserRouter 和 HashRouter:</h3>
<p>BrowserRouter(history模式) 和 HashRouter(hash模式)作为路由配置的最外层容器,是两种不同的模式,可根据需要选择。</p>
<p><strong>hash 模式:</strong></p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="25">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;import React, { Component } from 'react'\nimport { HashRouter, Route, Link } from 'react-router-dom'\nimport ThisCollapse from '@/components/ThisCollapse'\nimport ThisProgress from '@/components/ThisProgress'\nimport ThisTable from '@/components/ThisTable'\n\nexport default class App extends Component {\n render() {\n return (\n &lt;HashRouter&gt;\n &lt;div&gt;\n &lt;Route path=\&quot;/\&quot; exactcomponent={ThisTable}&gt;&lt;/Route&gt;\n &lt;Route path=\&quot;/a\&quot; exactcomponent={ThisCollapse} &gt;&lt;/Route&gt;\n &lt;Route path=\&quot;/b\&quot; exactcomponent={ThisProgress} &gt;&lt;/Route&gt;\n &lt;/div&gt;\n &lt;/HashRouter&gt;\n )\n }\n}\n&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><span class="hljs-keyword">import React, { Component } <span class="hljs-keyword">from <span class="hljs-string">'react'
<span class="hljs-keyword">import { HashRouter, Route, Link } <span class="hljs-keyword">from <span class="hljs-string">'react-router-dom'
<span class="hljs-keyword">import ThisCollapse <span class="hljs-keyword">from <span class="hljs-string">'@/components/ThisCollapse'
<span class="hljs-keyword">import ThisProgress <span class="hljs-keyword">from <span class="hljs-string">'@/components/ThisProgress'
<span class="hljs-keyword">import ThisTable <span class="hljs-keyword">from <span class="hljs-string">'@/components/ThisTable'
<span class="hljs-keyword">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Component {
render() {
<span class="hljs-keyword">return (
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">HashRouter>
<span class="hljs-tag"><<span class="hljs-name">div>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/" <span class="hljs-attr">exact<span class="hljs-attr">component=<span class="hljs-string">{ThisTable}><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/a" <span class="hljs-attr">exact<span class="hljs-attr">component=<span class="hljs-string">{ThisCollapse} ><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/b" <span class="hljs-attr">exact<span class="hljs-attr">component=<span class="hljs-string">{ThisProgress} ><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"></<span class="hljs-name">div>
<span class="hljs-tag"></<span class="hljs-name">HashRouter>
)
}
}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>通过“http://localhost:8080/#/a” 即可直接访问组件ThisCollapse。</p>
<p><strong>history 模式:</strong></p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="24">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;import React, { Component } from 'react'\nimport { BrowserRouter, Route, Link } from 'react-router-dom'\nimport ThisCollapse from '@/components/ThisCollapse'\nimport ThisProgress from '@/components/ThisProgress'\nimport ThisTable from '@/components/ThisTable'\n\nexport default class App extends Component {\n render() {\n return (\n &lt;BrowserRouter&gt;\n &lt;div&gt;\n &lt;Route path=\&quot;/\&quot; exactcomponent={ThisTable}&gt;&lt;/Route&gt;\n &lt;Route path=\&quot;/a\&quot; exactcomponent={ThisCollapse} &gt;&lt;/Route&gt;\n &lt;Route path=\&quot;/b\&quot; exactcomponent={ThisProgress} &gt;&lt;/Route&gt;\n &lt;/div&gt;\n &lt;/BrowserRouter&gt;\n )\n }\n}\n&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><span class="hljs-keyword">import React, { Component } <span class="hljs-keyword">from <span class="hljs-string">'react'
<span class="hljs-keyword">import { BrowserRouter, Route, Link } <span class="hljs-keyword">from <span class="hljs-string">'react-router-dom'
<span class="hljs-keyword">import ThisCollapse <span class="hljs-keyword">from <span class="hljs-string">'@/components/ThisCollapse'
<span class="hljs-keyword">import ThisProgress <span class="hljs-keyword">from <span class="hljs-string">'@/components/ThisProgress'
<span class="hljs-keyword">import ThisTable <span class="hljs-keyword">from <span class="hljs-string">'@/components/ThisTable'
<span class="hljs-keyword">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Component {
render() {
<span class="hljs-keyword">return (
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">BrowserRouter>
<span class="hljs-tag"><<span class="hljs-name">div>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/" <span class="hljs-attr">exact<span class="hljs-attr">component=<span class="hljs-string">{ThisTable}><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/a" <span class="hljs-attr">exact<span class="hljs-attr">component=<span class="hljs-string">{ThisCollapse} ><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/b" <span class="hljs-attr">exact<span class="hljs-attr">component=<span class="hljs-string">{ThisProgress} ><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"></<span class="hljs-name">div>
<span class="hljs-tag"></<span class="hljs-name">BrowserRouter>
)
}
}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>注意:当我们去访问localhost:8081/a这个地址的时候,webpack-dev-server会默认为你要访问服务器上的一个a页面。但我们的项目中只有一个index.html页面,并不存在list页面。所以它会提示你:Cannot GET /a(页面不存在)</p>
<p>在package.json中,我们可以使用webpack-dev-server中的 historyApiFallback 配置来解决此问题:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="23">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot; devServer: {\n historyApiFallback: true\n }&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"> devServer: {
<span class="hljs-attr">historyApiFallback: <span class="hljs-literal">true
}</span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>这样通过:“http://localhost:8080/a”可以直接访问组件ThisCollapse。</p>
<h3>4、路径匹配组件: Route 和 Switch:</h3>
<p><strong>Route: 用来控制路径对应显示的组件</strong></p>
<p>有以下几个参数:</p>
<p>4.1 path:指定路由跳转路径</p>
<p>4.2 exact: 精确匹配路由</p>
<p>4.3 component:路由对应的组件</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="22">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;import ThisCollapse from '@/components/ThisCollapse'\n\n...\n\n&lt;Route path=\&quot;/\&quot; exact component={ThisTable}&gt;&lt;/Route&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><span class="hljs-keyword">import ThisCollapse <span class="hljs-keyword">from <span class="hljs-string">'@/components/ThisCollapse'
...
<Route path=<span class="hljs-string">"/" exact component={ThisTable}><span class="xml"><span class="hljs-tag"></<span class="hljs-name">Route></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>4.4 render: 通过写render函数返回具体的dom:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="21">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Route path='/about' exact render={() =&gt; (&lt;div&gt;about&lt;/div&gt;)}&gt;&lt;/Route&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Route path=<span class="hljs-string">'/about' exact render={() => (<span class="xml"><span class="hljs-tag"><<span class="hljs-name">div>about<span class="hljs-tag"></<span class="hljs-name">div>)}><span class="xml"><span class="hljs-tag"></<span class="hljs-name">Route></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>render 也可以直接返回 About 组件,像下面:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="20">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Route path='/about' exact render={() =&gt; &lt;About /&gt; }&gt;&lt;/Route&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Route path=<span class="hljs-string">'/about' exact render={() => <span class="xml"><span class="hljs-tag"><<span class="hljs-name">About /> }><span class="hljs-tag"></<span class="hljs-name">Route></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>但是,这样写的好处是,不仅可以通过 render 方法传递 props 属性,并且可以传递自定义属性:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="19">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Route path='/about' exact render={(props) =&gt; {\n return &lt;About {...props} name={'cedric'} /&gt;\n}}&gt;&lt;/Route&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Route path=<span class="hljs-string">'/about' exact render={(props) => {
<span class="hljs-keyword">return <span class="xml"><span class="hljs-tag"><<span class="hljs-name">About {<span class="hljs-attr">...props} <span class="hljs-attr">name=<span class="hljs-string">{'<span class="hljs-attr">cedric'} />
}}><span class="hljs-tag"></<span class="hljs-name">Route></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>然后,就可在 About 组件中获取 props 和 name 属性:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="18">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;componentDidMount() {\n console.log(this.props) \n}\n\n\n// this.props:\n// history: {length: 9, action: \&quot;POP\&quot;, location: {…}, createHref: ƒ, push: ƒ, …}\n// location: {pathname: \&quot;/home\&quot;, search: \&quot;\&quot;, hash: \&quot;\&quot;, state: undefined, key: \&quot;ad7bco\&quot;}\n// match: {path: \&quot;/home\&quot;, url: \&quot;/home\&quot;, isExact: true, params: {…}}\n// name: \&quot;cedric\&quot;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs">componentDidMount() {
<span class="hljs-built_in">console.log(<span class="hljs-keyword">this.props)
}
<span class="hljs-comment">// this.props:
<span class="hljs-comment">// history: {length: 9, action: "POP", location: {…}, createHref: ƒ, push: ƒ, …}
<span class="hljs-comment">// location: {pathname: "/home", search: "", hash: "", state: undefined, key: "ad7bco"}
<span class="hljs-comment">// match: {path: "/home", url: "/home", isExact: true, params: {…}}
<span class="hljs-comment">// name: "cedric"</span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>render 方法也可用来进行权限认证:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="17">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Route path='/user' exact render={(props) =&gt; {\n // isLogin 从 redux 中拿到, 判断用户是否登录\n return isLogin ? &lt;User {...props} name={'cedric'} /&gt; : &lt;div&gt;请先登录&lt;/div&gt;\n}}&gt;&lt;/Route&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Route path=<span class="hljs-string">'/user' exact render={(props) => {
<span class="hljs-comment">// isLogin 从 redux 中拿到, 判断用户是否登录
<span class="hljs-keyword">return isLogin ? <span class="xml"><span class="hljs-tag"><<span class="hljs-name">User {<span class="hljs-attr">...props} <span class="hljs-attr">name=<span class="hljs-string">{'<span class="hljs-attr">cedric'} /> : <span class="hljs-tag"><<span class="hljs-name">div>请先登录<span class="hljs-tag"></<span class="hljs-name">div>
}}><span class="hljs-tag"></<span class="hljs-name">Route></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>4.5 location: 将 与当前历史记录位置以外的位置相匹配,则此功能在路由过渡动效中非常有用</p>
<p>4.6 sensitive:是否区分路由大小写</p>
<p>4.7 strict: 是否配置路由后面的 '/'</p>
<p><strong>Switch</strong></p>
<p>渲染与该地址匹配的第一个子节点 <Route> 或者 <Redirect>。</p>
<p>类似于选项卡,只是匹配到第一个路由后,就不再继续匹配:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="16">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot; &lt;BrowserRouter&gt;\n &lt;Switch&gt;\n &lt;Route path=\&quot;/\&quot; exact component={ThisTable}&gt;&lt;/Route&gt;\n &lt;Route path=\&quot;/a\&quot; exact component={ThisCollapse} &gt;&lt;/Route&gt;\n &lt;Route path=\&quot;/a\&quot; exact component={ThisProgress} &gt;&lt;/Route&gt;\n &lt;/Switch&gt;\n &lt;/BrowserRouter&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"> <BrowserRouter>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">Switch>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/" <span class="hljs-attr">exact <span class="hljs-attr">component=<span class="hljs-string">{ThisTable}><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/a" <span class="hljs-attr">exact <span class="hljs-attr">component=<span class="hljs-string">{ThisCollapse} ><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">"/a" <span class="hljs-attr">exact <span class="hljs-attr">component=<span class="hljs-string">{ThisProgress} ><span class="hljs-tag"></<span class="hljs-name">Route>
<span class="hljs-tag"></<span class="hljs-name">Switch>
<<span class="hljs-regexp">/BrowserRouter></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>此时,“http://localhost:8082/a”只能匹配到组件ThisCollapse。</p>
<p>所以,如果像下面这样:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="15">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Switch&gt; \n &lt;Route path='/home'component={Home}&gt;&lt;/Route&gt;\n &lt;Route path='/login'component={Login}&gt;&lt;/Route&gt; \n &lt;Route path='/detail'component={detail}&gt;&lt;/Route&gt; \n &lt;Route path='/detail/:id'component={detailId}&gt;&lt;/Route&gt; \n &lt;Redirect to=\&quot;/home\&quot; from='/' /&gt; \n&lt;/Switch&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Switch>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">'/home'<span class="hljs-attr">component=<span class="hljs-string">{Home}><span class="hljs-tag"></<span class="hljs-name">Route>
<Route path=<span class="hljs-string">'/login'component={Login}><span class="xml"><span class="hljs-tag"></<span class="hljs-name">Route>
<Route path=<span class="hljs-string">'/detail'component={detail}><span class="xml"><span class="hljs-tag"></<span class="hljs-name">Route>
<Route path=<span class="hljs-string">'/detail/:id'component={detailId}><span class="xml"><span class="hljs-tag"></<span class="hljs-name">Route>
<Redirect to=<span class="hljs-string">"/home" <span class="hljs-keyword">from=<span class="hljs-string">'/' />
<span class="xml"><span class="hljs-tag"></<span class="hljs-name">Switch></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>当路由为/detail/1时,只会访问匹配组件detail, 所以需要在detail路由上加上exact:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="14">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Switch&gt; \n &lt;Route path='/home'component={Home}&gt;&lt;/Route&gt;\n &lt;Route path='/login'component={Login}&gt;&lt;/Route&gt; \n &lt;Route path='/detail' exactcomponent={detail}&gt;&lt;/Route&gt; \n &lt;Route path='/detail/:id'component={detailId}&gt;&lt;/Route&gt; \n &lt;Redirect to=\&quot;/home\&quot; from='/' /&gt; \n&lt;/Switch&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Switch>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">'/home'<span class="hljs-attr">component=<span class="hljs-string">{Home}><span class="hljs-tag"></<span class="hljs-name">Route>
<Route path=<span class="hljs-string">'/login'component={Login}><span class="xml"><span class="hljs-tag"></<span class="hljs-name">Route>
<Route path=<span class="hljs-string">'/detail' exactcomponent={detail}><span class="xml"><span class="hljs-tag"></<span class="hljs-name">Route>
<Route path=<span class="hljs-string">'/detail/:id'component={detailId}><span class="xml"><span class="hljs-tag"></<span class="hljs-name">Route>
<Redirect to=<span class="hljs-string">"/home" <span class="hljs-keyword">from=<span class="hljs-string">'/' />
<span class="xml"><span class="hljs-tag"></<span class="hljs-name">Switch></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p> 注意:如果路由 Route 外部包裹 Switch 时,路由匹配到对应的组件后,就不会继续渲染其他组件了。但是如果外部不包裹 Switch 时,所有路由组件会先渲染一遍,然后选择到匹配的路由进行显示。</p>
<h3>5. 导航组件: Link 和 NavLink</h3>
<p>Link 和 NavLink 都可以用来指定路由跳转,NavLink 的可选参数更多。</p>
<p><strong>Link</strong></p>
<p>两种配置方式:</p>
<p>通过字符串执行跳转路由</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="13">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Link to='/login'&gt;\n &lt;span&gt;登录&lt;/span&gt;\n&lt;/Link&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Link to=<span class="hljs-string">'/login'>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">span>登录<span class="hljs-tag"></<span class="hljs-name">span>
<<span class="hljs-regexp">/Link></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>通过对象指定跳转路由</p>
<ul>
<li>pathname: 表示要链接到的路径的字符串。</li>
<li>search: 表示查询参数的字符串形式。</li>
<li>hash: 放入网址的 hash,例如 #a-hash。</li>
<li>state: 状态持续到 location。通常用于隐式传参(埋点),可以用来统计页面来源</li>
</ul>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="12">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Link to={{\n pathname: '/login',\n search: '?name=cedric',\n hash: '#someHash',\n state: { fromWechat: true }\n }}&gt;\n &lt;span&gt;登录&lt;/span&gt;\n&lt;/Link&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Link to={{
<span class="hljs-attr">pathname: <span class="hljs-string">'/login',
<span class="hljs-attr">search: <span class="hljs-string">'?name=cedric',
<span class="hljs-attr">hash: <span class="hljs-string">'#someHash',
<span class="hljs-attr">state: { <span class="hljs-attr">fromWechat: <span class="hljs-literal">true }
}}>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">span>登录<span class="hljs-tag"></<span class="hljs-name">span>
<<span class="hljs-regexp">/Link></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>点击链接 进入 Login 页面后,就可以在this.props.location.state中看到 fromWechat: true:</p>
<p><strong>NavLink</strong></p>
<p>可以看做 一个特殊版本的 Link,当它与当前 URL 匹配时,为其渲染元素添加样式属性。</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="11">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Link to='/login' activeClassName=\&quot;selected\&quot;&gt;\n &lt;span&gt;登录&lt;/span&gt;\n&lt;/Link&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Link to=<span class="hljs-string">'/login' activeClassName=<span class="hljs-string">"selected">
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">span>登录<span class="hljs-tag"></<span class="hljs-name">span>
<<span class="hljs-regexp">/Link></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="10">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;NavLink\nto=\&quot;/login\&quot;\nactiveStyle={{\n fontWeight: 'bold',\n color: 'red'\n }}\n&gt;\n &lt;span&gt;登录&lt;/span&gt;\n&lt;/NavLink&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><NavLink
to=<span class="hljs-string">"/login"
activeStyle={{
<span class="hljs-attr">fontWeight: <span class="hljs-string">'bold',
<span class="hljs-attr">color: <span class="hljs-string">'red'
}}
>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">span>登录<span class="hljs-tag"></<span class="hljs-name">span>
<<span class="hljs-regexp">/NavLink></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<ul>
<li>exact: 如果为 true,则仅在位置完全匹配时才应用 active 的类/样式。</li>
<li>strict: 当为 true,要考虑位置是否匹配当前的URL时,pathname 尾部的斜线要考虑在内。</li>
<li>location 接收一个location对象,当url满足这个对象的条件才会跳转</li>
<li>isActive: 接收一个回调函数,只有当 active 状态变化时才能触发,如果返回false则跳转失败</li>
</ul>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="9">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;const oddEvent = (match, location) =&gt; {\nif (!match) {\n return false\n}\nconst eventID = parseInt(match.params.eventID)\nreturn !isNaN(eventID) &amp;&amp; eventID % 2 === 1\n}\n\n&lt;NavLink\nto=\&quot;/login\&quot;\nisActive={oddEvent}\n&gt;login&lt;/NavLink&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><span class="hljs-keyword">const oddEvent = <span class="hljs-function">(<span class="hljs-params">match, location) => {
<span class="hljs-keyword">if (!match) {
<span class="hljs-keyword">return <span class="hljs-literal">false
}
<span class="hljs-keyword">const eventID = <span class="hljs-built_in">parseInt(match.params.eventID)
<span class="hljs-keyword">return !<span class="hljs-built_in">isNaN(eventID) && eventID % <span class="hljs-number">2 === <span class="hljs-number">1
}
<NavLink
to=<span class="hljs-string">"/login"
isActive={oddEvent}
>login<<span class="hljs-regexp">/NavLink></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<h3>6. Redirect</h3>
<p><Redirect> 将导航到一个新的地址。即重定向。</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="8">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Switch&gt; \n &lt;Route path='/home' exact component={Home}&gt;&lt;/Route&gt;\n &lt;Route path='/login' exact component={Login}&gt;&lt;/Route&gt; \n &lt;Redirect to=\&quot;/home\&quot; from='/' exact /&gt; \n&lt;/Switch&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Switch>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">Route <span class="hljs-attr">path=<span class="hljs-string">'/home' <span class="hljs-attr">exact <span class="hljs-attr">component=<span class="hljs-string">{Home}><span class="hljs-tag"></<span class="hljs-name">Route>
<Route path=<span class="hljs-string">'/login' exact component={Login}><span class="xml"><span class="hljs-tag"></<span class="hljs-name">Route>
<Redirect to=<span class="hljs-string">"/home" <span class="hljs-keyword">from=<span class="hljs-string">'/' exact />
<span class="xml"><span class="hljs-tag"></<span class="hljs-name">Switch></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>上面,当访问路由‘/’时,会直接重定向到‘/home’。</p>
<p><Redirect> 常在用户是否登录:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="7">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;class Center extends PureComponent {\n render() {\n const { loginStatus } = this.props;\n if (loginStatus) {\n return (\n &lt;div&gt;个人中心&lt;/div&gt;\n )\n } else {\n return &lt;Redirect to='/login' /&gt;\n }\n }\n}&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">Center <span class="hljs-keyword">extends <span class="hljs-title">PureComponent {
render() {
<span class="hljs-keyword">const { loginStatus } = <span class="hljs-keyword">this.props;
<span class="hljs-keyword">if (loginStatus) {
<span class="hljs-keyword">return (
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">div>个人中心<span class="hljs-tag"></<span class="hljs-name">div>
)
} <span class="hljs-keyword">else {
<span class="hljs-keyword">return <span class="xml"><span class="hljs-tag"><<span class="hljs-name">Redirect <span class="hljs-attr">to=<span class="hljs-string">'/login' />
}
}
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>也可使用对象形式:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="6">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;&lt;Redirect\nto={{\n pathname: \&quot;/login\&quot;,\n search: \&quot;?utm=your+face\&quot;,\n state: { referrer: currentLocation }\n}}\n/&gt;&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><Redirect
to={{
<span class="hljs-attr">pathname: <span class="hljs-string">"/login",
<span class="hljs-attr">search: <span class="hljs-string">"?utm=your+face",
<span class="hljs-attr">state: { <span class="hljs-attr">referrer: currentLocation }
}}
/></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<h3> 7. withRouter</h3>
<p>withRouter 可以将一个非路由组件包裹为路由组件,使这个非路由组件也能访问到当前路由的match, location, history对象。</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="5">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;import { withRouter } from 'react-router-dom';\n\nclass Detail extends Component {\n render() {\n ··· ···\n } \n}\n \nconst mapStateToProps = (state) =&gt; {\n return {\n ··· ···\n }\n}\n\nconst mapDispatchToProps = (dispatch) =&gt; {\n return {\n ··· ···\n }\n}\n \nexport default connect(mapStateToProps, mapDispatchToProps)(withRouter(Detail));&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><span class="hljs-keyword">import { withRouter } <span class="hljs-keyword">from <span class="hljs-string">'react-router-dom';
<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">Detail <span class="hljs-keyword">extends <span class="hljs-title">Component {
render() {
··· ···
}
}
<span class="hljs-keyword">const mapStateToProps = <span class="hljs-function">(<span class="hljs-params">state) => {
<span class="hljs-keyword">return {
··· ···
}
}
<span class="hljs-keyword">const mapDispatchToProps = <span class="hljs-function">(<span class="hljs-params">dispatch) => {
<span class="hljs-keyword">return {
··· ···
}
}
<span class="hljs-keyword">export <span class="hljs-keyword">default connect(mapStateToProps, mapDispatchToProps)(withRouter(Detail));</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<h3>8. 编程式导航 - history 对象</h3>
<p>例如,点击img进入登录页:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="4">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;class Home extends PureComponent {\n\n goHome = () =&gt; {\n console.log(this.props);\n \n this.props.history.push({\n pathname: '/login',\n state: {\n identityId: 1\n }\n })\n }\n\n render() {\n return (\n &lt;img className='banner-img' alt='' src=\&quot;img.png\&quot; onClick={this.goHome} /&gt;\n )\n } \n}&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">Home <span class="hljs-keyword">extends <span class="hljs-title">PureComponent {
goHome = <span class="hljs-function"><span class="hljs-params">() => {
<span class="hljs-built_in">console.log(<span class="hljs-keyword">this.props);
<span class="hljs-keyword">this.props.history.push({
<span class="hljs-attr">pathname: <span class="hljs-string">'/login',
<span class="hljs-attr">state: {
<span class="hljs-attr">identityId: <span class="hljs-number">1
}
})
}
render() {
<span class="hljs-keyword">return (
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">img <span class="hljs-attr">className=<span class="hljs-string">'banner-img' <span class="hljs-attr">alt=<span class="hljs-string">'' <span class="hljs-attr">src=<span class="hljs-string">"img.png" <span class="hljs-attr">onClick=<span class="hljs-string">{this.goHome} />
)
}
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p> history 对象通常会具有以下属性和方法:</p>
<blockquote>
<ul>
<li>length - (number 类型) history 堆栈的条目数</li>
<li>action - (string 类型) 当前的操作(PUSH, REPLACE, POP)</li>
<li>location - (object 类型) 当前的位置。location 会具有以下属性:</li>
<li>pathname - (string 类型) URL 路径</li>
<li>search - (string 类型) URL 中的查询字符串</li>
<li>hash - (string 类型) URL 的哈希片段</li>
<li>state - (object 类型) 提供给例如使用 push(path, state) 操作将 location 放入堆栈时的特定 location 状态。只在浏览器和内存历史中可用。</li>
<li>push(path, ) - (function 类型) 在 history 堆栈添加一个新条目</li>
<li>replace(path, ) - (function 类型) 替换在 history 堆栈中的当前条目</li>
<li>go(n) - (function 类型) 将 history 堆栈中的指针调整 n</li>
<li>goBack() - (function 类型) 等同于 go(-1)</li>
<li>goForward() - (function 类型) 等同于 go(1)</li>
<li>block(prompt) - (function 类型) 阻止跳转。 </li>
</ul>
</blockquote>
<p>注意,只有通过 Route 组件渲染的组件,才能在 this.props 上找到 history 对象</p>
<p>所以,如果想在路由组件的子组件中使用 history ,需要使用 withRouter 包裹:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="3">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;import React, { PureComponent } from 'react';\nimport { withRouter } from 'react-router-dom';\n\nclass 子组件 extends PureComponent {\n\n goHome = () =&gt; {\n this.props.history.push('/home')\n }\n\n\n render() {\n console.log(this.props)\n return (\n &lt;div onClick={this.goHome}&gt;子组件&lt;/div&gt;\n )\n }\n}\n\nexport default withRouter(子组件);&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><span class="hljs-keyword">import React, { PureComponent } <span class="hljs-keyword">from <span class="hljs-string">'react';
<span class="hljs-keyword">import { withRouter } <span class="hljs-keyword">from <span class="hljs-string">'react-router-dom';
<span class="hljs-class"><span class="hljs-keyword">class 子组件 <span class="hljs-keyword">extends <span class="hljs-title">PureComponent {
goHome = <span class="hljs-function"><span class="hljs-params">() => {
<span class="hljs-keyword">this.props.history.push(<span class="hljs-string">'/home')
}
render() {
<span class="hljs-built_in">console.log(<span class="hljs-keyword">this.props)
<span class="hljs-keyword">return (
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">div <span class="hljs-attr">onClick=<span class="hljs-string">{this.goHome}>子组件<span class="hljs-tag"></<span class="hljs-name">div>
)
}
}
<span class="hljs-keyword">export <span class="hljs-keyword">default withRouter(子组件);</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<h3>9. 路由过渡动画</h3>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="2">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;import { TransitionGroup, CSSTransition } from \&quot;react-transition-group\&quot;;\n\nclass App extends Component {\n\nrender() {\n return (\n &lt;Provider store={store}&gt;\n &lt;Fragment&gt; \n &lt;BrowserRouter&gt;\n &lt;div&gt;\n &lt;Header /&gt;\n \n {/* 最外部的&lt;Route&gt;&lt;/Route&gt;不进行任何路由匹配,仅仅是用来传递 location */}\n \n &lt;Route render={({location}) =&gt; {\n console.log(location);\n return (\n &lt;TransitionGroup&gt;\n &lt;CSSTransition\n key={location.key}\n classNames='fade'\n timeout={300}\n &gt;\n &lt;Switch&gt;\n &lt;Redirect exact from='/' to='/home' /&gt;\n &lt;Route path='/home' exact component={Home}&gt;&lt;/Route&gt;\n &lt;Route path='/login' exact component={Login}&gt;&lt;/Route&gt;\n &lt;Route path='/write' exact component={Write}&gt;&lt;/Route&gt;\n &lt;Route path='/detail/:id' exact component={Detail}&gt;&lt;/Route&gt;\n &lt;Route render={() =&gt; &lt;div&gt;Not Found&lt;/div&gt;} /&gt;\n &lt;/Switch&gt;\n &lt;/CSSTransition&gt;\n &lt;/TransitionGroup&gt;\n )\n }}&gt;\n &lt;/Route&gt;\n &lt;/div&gt;\n &lt;/BrowserRouter&gt;\n &lt;/Fragment&gt;\n &lt;/Provider&gt;\n )\n}\n}&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs"><span class="hljs-keyword">import { TransitionGroup, CSSTransition } <span class="hljs-keyword">from <span class="hljs-string">"react-transition-group";
<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Component {
render() {
<span class="hljs-keyword">return (
<Provider store={store}>
<Fragment>
<BrowserRouter>
<div>
<Header />
{/* 最外部的<Route></Route>不进行任何路由匹配,仅仅是用来传递 location */}
<Route render={({location}) => {
console.log(location);
return (
<TransitionGroup>
<CSSTransition
key={location.key}
classNames='fade'
timeout={300}
>
<Switch>
<Redirect exact from='/' to='/home' />
<Route path='/home' exact component={Home}></Route>
<Route path='/login' exact component={Login}></Route>
<Route path='/write' exact component={Write}></Route>
<Route path='/detail/:id' exact component={Detail}></Route>
<Route render={() => <div>Not Found</div>} />
</Switch>
</CSSTransition>
</TransitionGroup>
)
}}>
</Route>
</div>
</BrowserRouter>
</Fragment>
</Provider>
)
}
}</span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="1">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;css&quot;,&quot;code&quot;:&quot;.fade-enter {\nopacity: 0;\nz-index: 1;\n}\n\n.fade-enter.fade-enter-active {\nopacity: 1;\ntransition: opacity 300ms ease-in;\n}&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-css hljs"><span class="hljs-selector-class">.fade-enter {
<span class="hljs-attribute">opacity: <span class="hljs-number">0;
<span class="hljs-attribute">z-index: <span class="hljs-number">1;
}
<span class="hljs-selector-class">.fade-enter<span class="hljs-selector-class">.fade-enter-active {
<span class="hljs-attribute">opacity: <span class="hljs-number">1;
<span class="hljs-attribute">transition: opacity <span class="hljs-number">300ms ease-in;
}</span></span></span></span></span></span></span></span></span></span></span></code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<h3>10. 打包部署的路由配置</h3>
<p>项目执行npm run build后,将打包后的build文件当大 Nginx 配置中。</p>
<p>如果 react-router 路由 使用了 history 模式(即<BrowserRouter>),那么在 Nginx 配置中必须加上:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="0">
<pre class="cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;javascript&quot;,&quot;code&quot;:&quot;location / {\n ··· ···\n try_files $uri /index.html;\n ··· ···\n }\n }&quot;,&quot;classes&quot;:[]}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-javascript hljs">location / {
··· ···
try_files $uri /index.html;
··· ···
}
}</code></pre>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>如果 react-router 路由 使用了 hash 模式(即<HashRouter>),那么在 Nginx 中不需要上面的配置。</p><br><br>
来源:https://www.cnblogs.com/samve/p/12435908.html
頁:
[1]