今天来说说,react 的路由缓存,这个在react 中很少有实质性可用的资料!此篇记录一下
demo 请狠狠的戳这里 ¥ http://download.lllomh.com/cliect/#/product/J804099672377354
demo 请狠狠的戳这里 c https://download.csdn.net/download/lllomh/12684925
导入 之后 :
import {
Provider,
KeepAlive,
} from 'react-keep-alive';
在路由阶段包括起来必须在Router 里层
<Router>
<Provider include={['Home','Detaile']}> {/*include ={['Home']} include="a,b" 为组件的弹出名字 匹配就缓存 不写则全部缓存*/}
{/*<Switch>*/}
{/* <Route path='/' exact component={Home}/>*/}
{/* <Route path='/home' exact component={Home}/>*/}
{/* <Route path='/detial' exact component={Detaile}/>*/}
{/*</Switch>*/}
<Switch>
<Route path="/home">
<KeepAlive name="Home">
<Home />
</KeepAlive>
</Route>
<Route path="/detial">
<KeepAlive name="Detaile">
<Detaile />
</KeepAlive>
</Route>
</Switch>
</Provider>
</Router>
<Provider include={['Home','Detaile']}> 参照 官方文档 https://github.com/lllomh/react-keep-alive
代码:
import React, {Component} from "react"
import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom"
import axios from 'axios'
import {
Provider,
KeepAlive,
} from 'react-keep-alive';
/**路由页面**/
import Home from '../pages/index'
import Detaile from '../pages/detaile'
React.Component.prototype.$axios = axios;
class Routers extends Component {
render() {
return (
<div>
<Router>
<Provider include={['Home','Detaile']}> {/*include ={['Home']} include="a,b" 为组件的弹出名字 匹配就缓存 不写则全部缓存*/}
{/*<Switch>*/}
{/* <Route path='/' exact component={Home}/>*/}
{/* <Route path='/home' exact component={Home}/>*/}
{/* <Route path='/detial' exact component={Detaile}/>*/}
{/*</Switch>*/}
<Switch>
<Route path="/home">
<KeepAlive name="Home">
<Home />
</KeepAlive>
</Route>
<Route path="/detial">
<KeepAlive name="Detaile">
<Detaile />
</KeepAlive>
</Route>
</Switch>
</Provider>
</Router>
</div>
)
}
}
export default Routers
最后强调一点,要返回操作返回到之前的列表的滚动条位置,需要用
import {createBrowserHistory} from 'history' comeBack=()=>{ const customHistory = createBrowserHistory(); customHistory.goBack(); }
来实现,
"react-keep-alive": "^2.5.2", "react-router-dom": "^5.2.0",
版本中
react-keep-alive中有2个使用较多的 生命周期:
进入组件页面的时候 触发:
componentDidActivate(){ let home = this.$Tool.getUrlKey("from") this.setState({ isHome:!!home }) }
离开组件页面的时候触发:
componentWillUnactivate(){ console.log(444) }
总体:
componentDidMount(){ console.log('ssssssssssssssssss') this.init() this.getWatch() } componentDidActivate(){ console.log(3333) let home = this.$Tool.getUrlKey("from") this.setState({ isHome:!!home }) } componentWillUnactivate(){ console.log(444) }
实际线上案例:
FrontendAuth.jsx
if (targetRouterConfig && !targetRouterConfig.auth && !isLogin) {
const { component,name } = targetRouterConfig;
let Components = component
return <Route exact path={pathname}>
<KeepAlive name={name}>
<Components/>
</KeepAlive>
</Route>;
}
router/index.jsx
<Router>
<ScrollToTop>
<Headers/>
<Provider>
<Switch>
<FrontendAuth routerConfig={routerMap} />
</Switch>
</Provider>
<Footer/>
</ScrollToTop>
</Router>
productDetails.jsx
componentDidActivate(){
console.log(3333)
let home = this.$Tool.getUrlKey("from")
this.setState({
isHome:!!home
})
}
componentWillUnactivate(){
console.log(444)
}
productDetails.jsx
resetOrNot=()=>{
this.state.isHome?this.$Tool.comeBack():this.props.history.push('/');
}
最后还是强调重点,这缓存的情况是,只有返回上一步的操作的时候才会定位到原来的滚动条位置,跳转的话,缓存是可以.但滚动位置不会记录.不会再发请求.包括componentWillReceiveProps在内的生命周期都会失效:
只保留 keep-alvie 的生命周期外 shouldComponentUpdate(nextProps,nextState){}、componentDidUpdate(newProps,newState,Snapshot){}
这2个数据生命周期还保留,其他的不执行!
加 Product = bindLifecycle(Product) 的情况下 componentDidUpdate 有效 componentWillReceiveProps不确定,有时有有效,可能有其他原因
componentDidUpdate(prevProps, prevState, snapshot){
console.log(111111)
let categoryId = this.$Tool.getUrlKey("categoryId")
if(categoryId!=null){
if(categoryId!=this.state.categoryId){
this.init()
}
}
}
这点有点商榷,欢迎大家查证