陆星言 發表於 2019-7-25 21:06:00

react-router-cache-router

<h1>转载---官方文档:<span style="font-size: 18px">https://github.com/CJY0208/react-router-cache-route/blob/master/README_CN.md</span></h1>
<p>&nbsp;</p>
<hr>
<p>&nbsp;</p>
<h1>CacheRoute</h1>
<p>搭配&nbsp;<code>react-router</code>&nbsp;工作的、带缓存功能的路由组件,类似于&nbsp;<code>Vue</code>&nbsp;中的&nbsp;<code>keep-alive</code>&nbsp;功能</p>
<p>React v15+</p>
<p>React-Router v4+</p>
<h2>遇到的问题</h2>
<p>使用&nbsp;<code>Route</code>&nbsp;时,路由对应的组件在前进或后退无法被缓存,导致了&nbsp;数据和行为的丢失</p>
<p>例如:列表页滚动到底部后,点击跳转到详情页,返回后会回到列表页顶部,丢失了滚动位置和数据的记录</p>
<h2>原因 &amp; 解决方案</h2>
<p><code>Route</code>&nbsp;中配置的组件在路径不匹配时会被卸载(render 方法中 return null),对应的真实节点也将从 dom 树中删除</p>
<p>在阅读了&nbsp;<code>Route</code>&nbsp;的源码后我们发现可以将&nbsp;<code>children</code>&nbsp;当作方法来使用,以帮助我们手动控制渲染的行为</p>
<p>隐藏替代删除&nbsp;可以解决遇到的问题</p>
<p>https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Route.js#L42-L63</p>
<h2>安装</h2>
<div class="highlight highlight-source-shell">
<pre>npm install react-router-cache-route --save<br><br></pre>
<h2>使用方法</h2>
<p>可以使用&nbsp;<code>CacheRoute</code>&nbsp;组件的&nbsp;<code>component</code>,&nbsp;<code>render</code>,&nbsp;<code>children</code>&nbsp;属性装载组件</p>
<p>注意:缓存语句不要写在&nbsp;<code>Switch</code>&nbsp;组件当中,因为&nbsp;<code>Switch</code>&nbsp;组件会卸载掉所有非匹配状态下的路由,需使用&nbsp;<code>CacheSwitch</code>替代&nbsp;<code>Switch</code></p>
<p>使用&nbsp;<code>when</code>&nbsp;属性决定何时使用缓存功能,可选值为 [<code>forward</code>,&nbsp;<code>back</code>,&nbsp;<code>always</code>] ,默认值为&nbsp;<code>forward</code></p>
<p>使用&nbsp;<code>className</code>&nbsp;属性给包裹组件添加自定义样式</p>
<p>也可以使用&nbsp;<code>behavior</code>&nbsp;属性来自定义缓存状态下组件的隐藏方式,工作方式是根据&nbsp;<code>CacheRoute</code>&nbsp;当前的缓存状态,返回一个作用于包裹组件的&nbsp;<code>props</code></p>
<div class="cnblogs_code">
<pre>import React from 'react'<span style="color: rgba(0, 0, 0, 1)">
import { HashRouter as Router, Switch, Route } from </span>'react-router-dom'<span style="color: rgba(0, 0, 0, 1)">
import CacheRoute, { CacheSwitch } from </span>'react-router-cache-route'<span style="color: rgba(0, 0, 0, 1)">

import List from </span>'./components/List'<span style="color: rgba(0, 0, 0, 1)">
import Item from </span>'./components/Item'<span style="color: rgba(0, 0, 0, 1)">

import List2 from </span>'./components/List2'<span style="color: rgba(0, 0, 0, 1)">
import Item2 from </span>'./components/Item2'<span style="color: rgba(0, 0, 0, 1)">

const App </span>= () =&gt;<span style="color: rgba(0, 0, 0, 1)"> (
</span>&lt;Router&gt;<span style="color: rgba(0, 0, 0, 1)">
    {</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
      也可使用 render, children prop
      &lt;CacheRoute exact path="/list" render={props =&gt; &lt;List {...props} /&gt;} /&gt;
      或
      &lt;CacheRoute exact path="/list"&gt;
      {props =&gt; &lt;List {...props} /&gt;}
      &lt;/CacheRoute&gt;
      或
      &lt;CacheRoute exact path="/list"&gt;
      &lt;div&gt;
          支持多个子组件
      &lt;/div&gt;
      &lt;List /&gt;
      &lt;/CacheRoute&gt;
    </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">}
    </span>&lt;CacheRoute exact path="/list" component={List} when="always" /&gt;
    &lt;Switch&gt;
      &lt;Route exact path="/item/:id" component={Item} /&gt;
    &lt;/Switch&gt;

    &lt;CacheSwitch&gt;
      &lt;<span style="color: rgba(0, 0, 0, 1)">CacheRoute
      exact
      path</span>="/list2"<span style="color: rgba(0, 0, 0, 1)">
      component</span>=<span style="color: rgba(0, 0, 0, 1)">{List2}
      className</span>="custom-style"<span style="color: rgba(0, 0, 0, 1)">
      behavior</span>={cached =&gt; (cached ?<span style="color: rgba(0, 0, 0, 1)"> {
          style: {
            position: </span>'absolute'<span style="color: rgba(0, 0, 0, 1)">,
            zIndex: </span>-9999<span style="color: rgba(0, 0, 0, 1)">,
            opacity: </span>0<span style="color: rgba(0, 0, 0, 1)">,
            visibility: </span>'hidden'<span style="color: rgba(0, 0, 0, 1)">,
            pointerEvents: </span>'none'<span style="color: rgba(0, 0, 0, 1)">
          },
          className: </span>'__CacheRoute__wrapper__cached'<span style="color: rgba(0, 0, 0, 1)">
      } : {
          className: </span>'__CacheRoute__wrapper__uncached'<span style="color: rgba(0, 0, 0, 1)">
      })}
      </span>/&gt;
      &lt;Route exact path="/item2/:id" component={Item2} /&gt;
      &lt;<span style="color: rgba(0, 0, 0, 1)">Route
      render</span>={() =&gt;<span style="color: rgba(0, 0, 0, 1)"> (
          </span>&lt;div&gt;404 未找到页面&lt;/div&gt;
<span style="color: rgba(0, 0, 0, 1)">      )}
      </span>/&gt;
    &lt;/CacheSwitch&gt;
&lt;/Router&gt;
<span style="color: rgba(0, 0, 0, 1)">)

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> App</pre>
</div>
<h2>额外的生命周期</h2>
<p>使用&nbsp;<code>CacheRoute</code>&nbsp;的组件将会得到一个名为&nbsp;<code>cacheLifecycles</code>&nbsp;的属性,里面包含两个额外生命周期的注入函数&nbsp;<code>didCache</code>&nbsp;和&nbsp;<code>didRecover</code>,分别用在组件&nbsp;被缓存&nbsp;和&nbsp;被恢复&nbsp;时</p>
<div class="cnblogs_code">
<pre>import React, { Component } from 'react'<span style="color: rgba(0, 0, 0, 1)">

export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> class List extends Component {
constructor(props, ...args) {
    super(props, ...args)

    props.cacheLifecycles.didCache(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.componentDidCache)
    props.cacheLifecycles.didRecover(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.componentDidRecover)
}

componentDidCache </span>= () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    console.log(</span>'List cached'<span style="color: rgba(0, 0, 0, 1)">)
}

componentDidRecover </span>= () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    console.log(</span>'List recovered'<span style="color: rgba(0, 0, 0, 1)">)
}

render() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...</span>
<span style="color: rgba(0, 0, 0, 1)">    )
}
}</span></pre>
</div>
<h2>手动清除缓存</h2>
<p>使用&nbsp;<code>cacheKey</code>&nbsp;prop 和&nbsp;<code>dropByCacheKey</code>&nbsp;函数来手动控制缓存</p>
<div class="cnblogs_code">
<pre>import CacheRoute, { dropByCacheKey, getCachingKeys } from 'react-router-cache-route'<span style="color: rgba(0, 0, 0, 1)">

...
</span>&lt;CacheRoute ... cacheKey="MyComponent" /&gt;
<span style="color: rgba(0, 0, 0, 1)">...

console.log(getCachingKeys()) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 如果 `cacheKey` prop 为 'MyComponent' 的缓存路由已处于缓存状态,将得到 ['MyComponent']</span>
<span style="color: rgba(0, 0, 0, 1)">...

dropByCacheKey(</span>'MyComponent'<span style="color: rgba(0, 0, 0, 1)">)
...</span></pre>
</div>
<p>&nbsp;</p>
</div><br><br>
来源:https://www.cnblogs.com/r-mp/p/11246985.html
頁: [1]
查看完整版本: react-router-cache-router