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> </p>
<hr>
<p> </p>
<h1>CacheRoute</h1>
<p>搭配 <code>react-router</code> 工作的、带缓存功能的路由组件,类似于 <code>Vue</code> 中的 <code>keep-alive</code> 功能</p>
<p>React v15+</p>
<p>React-Router v4+</p>
<h2>遇到的问题</h2>
<p>使用 <code>Route</code> 时,路由对应的组件在前进或后退无法被缓存,导致了 数据和行为的丢失</p>
<p>例如:列表页滚动到底部后,点击跳转到详情页,返回后会回到列表页顶部,丢失了滚动位置和数据的记录</p>
<h2>原因 & 解决方案</h2>
<p><code>Route</code> 中配置的组件在路径不匹配时会被卸载(render 方法中 return null),对应的真实节点也将从 dom 树中删除</p>
<p>在阅读了 <code>Route</code> 的源码后我们发现可以将 <code>children</code> 当作方法来使用,以帮助我们手动控制渲染的行为</p>
<p>隐藏替代删除 可以解决遇到的问题</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>可以使用 <code>CacheRoute</code> 组件的 <code>component</code>, <code>render</code>, <code>children</code> 属性装载组件</p>
<p>注意:缓存语句不要写在 <code>Switch</code> 组件当中,因为 <code>Switch</code> 组件会卸载掉所有非匹配状态下的路由,需使用 <code>CacheSwitch</code>替代 <code>Switch</code></p>
<p>使用 <code>when</code> 属性决定何时使用缓存功能,可选值为 [<code>forward</code>, <code>back</code>, <code>always</code>] ,默认值为 <code>forward</code></p>
<p>使用 <code>className</code> 属性给包裹组件添加自定义样式</p>
<p>也可以使用 <code>behavior</code> 属性来自定义缓存状态下组件的隐藏方式,工作方式是根据 <code>CacheRoute</code> 当前的缓存状态,返回一个作用于包裹组件的 <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>= () =><span style="color: rgba(0, 0, 0, 1)"> (
</span><Router><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
<CacheRoute exact path="/list" render={props => <List {...props} />} />
或
<CacheRoute exact path="/list">
{props => <List {...props} />}
</CacheRoute>
或
<CacheRoute exact path="/list">
<div>
支持多个子组件
</div>
<List />
</CacheRoute>
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">}
</span><CacheRoute exact path="/list" component={List} when="always" />
<Switch>
<Route exact path="/item/:id" component={Item} />
</Switch>
<CacheSwitch>
<<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 => (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>/>
<Route exact path="/item2/:id" component={Item2} />
<<span style="color: rgba(0, 0, 0, 1)">Route
render</span>={() =><span style="color: rgba(0, 0, 0, 1)"> (
</span><div>404 未找到页面</div>
<span style="color: rgba(0, 0, 0, 1)"> )}
</span>/>
</CacheSwitch>
</Router>
<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>使用 <code>CacheRoute</code> 的组件将会得到一个名为 <code>cacheLifecycles</code> 的属性,里面包含两个额外生命周期的注入函数 <code>didCache</code> 和 <code>didRecover</code>,分别用在组件 被缓存 和 被恢复 时</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>= () =><span style="color: rgba(0, 0, 0, 1)"> {
console.log(</span>'List cached'<span style="color: rgba(0, 0, 0, 1)">)
}
componentDidRecover </span>= () =><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>使用 <code>cacheKey</code> prop 和 <code>dropByCacheKey</code> 函数来手动控制缓存</p>
<div class="cnblogs_code">
<pre>import CacheRoute, { dropByCacheKey, getCachingKeys } from 'react-router-cache-route'<span style="color: rgba(0, 0, 0, 1)">
...
</span><CacheRoute ... cacheKey="MyComponent" />
<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> </p>
</div><br><br>
来源:https://www.cnblogs.com/r-mp/p/11246985.html
頁:
[1]