牛叉的react-router-cache-route
CacheRoute
github地址 搭配 react-router 工作的、帶快取功能的路由元件,類似於 Vue 中的 keep-alive 功能
注意:目前只在 路由前進時 進行快取
React v16.3+ (相容了 React v16.3 以下版本)
React-Router v4+
遇到的問題
使用 Route 時,路由對應的元件在前進或後退無法被快取,導致了 資料和行為的丟失
例如:列表頁滾動到底部後,點選跳轉到詳情頁,返回後會回到列表頁頂部,丟失了滾動位置和資料的記錄
原因 & 解決方案
Route 中配置的元件在路徑不匹配時會被解除安裝(render 方法中 return null
在閱讀了 Route 的原始碼後我們發現可以將 children 當作方法來使用,以幫助我們手動控制渲染的行為
安裝
npm install react-router-cache-route --save
使用方法
可以使用 CacheRoute
元件的 component
, render
, children
屬性裝載元件,或者
配合 Route 元件的 children 屬性使用 cacheComponent 方法
注意:快取語句不要寫在 Switch
元件當中,因為 Switch
元件會解除安裝掉所有非匹配狀態下的路由,需使用 CacheSwitch
Switch
使用 when
屬性決定何時使用快取功能,可選值為 [forward, back, always
] ,預設值為 forward
使用 className
屬性給包裹元件新增自定義樣式
也可以使用 behavior
屬性來自定義快取狀態下元件的隱藏方式,工作方式是根據 CacheRoute
當前的快取狀態,返回一個作用於包裹元件的 props
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> {/* 也可使用 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> */} <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__wrapper__cached' } : { className: '__CacheRoute__wrapper__uncached' })} /> <Route exact path="/item2/:id" component={Item2} /> <Route render={() => ( <div>404 未找到頁面</div> )} /> </CacheSwitch> </Router> ) export default App
額外的生命週期
使用 CacheRoute
的元件將會得到一個名為 cacheLifecycles
的屬性,裡面包含兩個額外生命週期的注入函式 didCache
和 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 (
// ...
)
}
}