Route with cache for react-router like keep-alive in Vue.
Will cache the Route ONLY while going forward
React v16.3+ (Compatible React 16.3- now)
React-Router v4+
Using Route, component can not be cached while going forward or back which lead to losing data and interaction
Component would be unmounted when Route was unmatched
After reading source code of Route we found that using children prop as a function could help to control rendering behavior.
Hiding instead of Removing would fix this issue.
npm install react-router-cache-route --saveCan use CacheRoute with component, render, children prop, or
Using cacheComponent work with Route's children prop
DO NOT put it in Switch component, use CacheSwitch instead
Use when prop to decide when you need to use the cache, the optional value is [forward, back, always] , forward default
Use className prop for adding custom style to the cache wrapper component
You can also customize how the cached components are hidden using behavior props which would return a props effective on the wrapper component
import React from 'react'
import { HashRouter as Router, Switch, Route } from 'react-router-dom'
import CacheRoute, { CacheSwitch } from 'react-router-cache-route'
import List from './components/List'
import Item from './components/Item'
import List2 from './components/List2'
import Item2 from './components/Item2'
const App = () => (
<Router>
{/*
Can also use render, children props
<CacheRoute exact path="/list" render={props => <List {...props} />} />
or
<CacheRoute exact path="/list">
{props => <List {...props} />}
</CacheRoute>
or
<CacheRoute exact path="/list">
<div>
Support muiltple children
</div>
<List />
</CacheRoute>
*/}
<CacheRoute exact path="/list" component={List} when="always" />
<Switch>
<Route exact path="/item/:id" component={Item} />
</Switch>
<CacheSwitch>
<CacheRoute
exact
path="/list2"
component={List2}
className="custom-style"
behavior={cached => (cached ? {
style: {
position: 'absolute',
zIndex: -9999,
opacity: 0,
visibility: 'hidden',
pointerEvents: 'none'
},
className: '__CacheRoute__cached'
} : {
className: '__CacheRoute__uncached'
})}
/>
<Route exact path="/item2/:id" component={Item2} />
<Route
render={() => (
<div>404 Not Found</div>
)}
/>
</CacheSwitch>
</Router>
)
export default AppComponent with CacheRoute will accept one prop named cacheLifecycles which contains two functions to inject customer Lifecycle didCache and didRecover
import React, { Component } from 'react'
export default class List extends Component {
constructor(props, ...args) {
super(props, ...args)
props.cacheLifecycles.didCache(this.componentDidCache)
props.cacheLifecycles.didRecover(this.componentDidRecover)
}
componentDidCache = () => {
console.log('List cached')
}
componentDidRecover = () => {
console.log('List recovered')
}
render() {
return (
// ...
)
}
}