怎么使用react-mile米乐体育
怎么使用react-activation实现keepalive支持返回传参
这篇文章主要介绍“怎么使用react-activation实现keepalive支持返回传参”,在日常操作中,相信很多人在怎么使用react-activation实现keepalive支持返回传参问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么使用react-activation实现keepalive支持返回传参”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
介绍
这个项目是一个商城的后台管理系统,用umi2.0搭建,状态管理使用dva,想要实现类似vue keep-alive的效果。
具体表现为:
从列表页a跳转a的详情页,列表页a缓存
详情页没做任何操作,跳回列表页a,列表页a不刷新,列表页a页码不变
详情页进行了编辑操作,跳回列表页a,列表页a刷新,列表页a页码不变
详情页进行了新建操作,跳回列表页a,列表页a刷新,列表页a页码变为1
从列表页a跳转列表页b,列表页a不缓存
总结就是,一个页面只有跳转指定页面的时候才缓存,并且当返回这个被缓存的页面时,可以控制是否刷新。
代码
1、安装react-activation
"react-activation":"^0.10.2",
2、给路由增加meta
这个项目使用的是集中式配置路由,我增加了meta属性,meta.keepalive存在表示这是一个需要被keepalive的路由,meta.keepalive.topath表示只有当前往这个路由的时候,需要缓存
constroutes=[...{name:'商品管理(商城商品)',path:'/web/supplier/goods/mallgoodsmgr',component:'./supplier/goods/goodsmanage',meta:{keepalive:{topath:'/web/supplier/goods/mallgoodsmgr/detail',//只有去详情页的时候才需要缓存商品管理(商城商品)这个路由},},}...]
3、根组件中渲染
在根组件中,用
通过tree的扁平化计算获取全部的带有meta.keepalive的routes:keepaliveroutes,通过location.pathname判断,如果当前页面是需要keepalive的,那么就需要用
importkeepalive,{alivescope,usealivecontroller}from'react-activation'//tree扁平化functiontreetolist(tree,childrenkey='routes'){varqueen=[]varout=[]queen=queen.concat(tree)while(queen.length){varfirst=queen.shift()if(first[childrenkey]){queen=queen.concat(first[childrenkey])deletefirst[childrenkey]}out.push(first)}returnout}//从routes路由tree里,拿到所有meta.keepalive的路由:keepaliveroutesconstallflatroutes=treetolist(routes)//所有路由constkeepaliveroutes=allflatroutes.filter((item)=>item.meta?.keepalive)//keepalive的路由functionindex(props){constlocation=uselocation()constrouteitem=keepaliveroutes.find((item)=>item.path==location.pathname)//from页面letdom=props.childrenif(routeitem){dom={props.children}//id一定要加否则keepalive的页面跳转另一个keepalive的页面会有问题}return( {dom}
注意alivescope中包含多个keepalive的话,
4、跳转指定页面的时候才缓存
上一步之后,页面虽然被缓存,但是它跳转任何页面都会缓存,我们需要只有跳转指定页面的时候才缓存。
我的方法是
如果跳转的页面正好是它自己的meta.keepalive.topath,那就不做任何操作(因为此时本页面已经被keepalive包裹了,处于缓存的状态)
如果不是它自己的meta.keepalive.topath,调用clear方法,清空缓存
4.1 clear方法
react-activation提供usealivecontroller可以手动控制缓存,其中clear方法用于清空所有缓存中的 keepalive
4.2 用状态管理记录topath
监听history,用状态管理(我用的dva)记录即将前往的页面(下一个页面)topath
我通过dva记录应用即将前往的页面
constglobalmodel={namespace:'global',state:{/***keepalive*/topath:'',keepaliveoptions:{},//给keepalive的页面传的options},effects:{},reducers:{save(state,{payload}){return{...state,...payload,}},settopath(state,{payload}){return{...state,topath:payload,}},},subscriptions:{setup({history,dispatch}){//subscribehistory(url)change,trigger`load`actionifpathnameis`/`history.listen((route,typestr)=>{const{pathname}=routedispatch({type:'settopath',payload:pathname,})})},},}
4.3 给根组件增加useeffect
根组件从dva中读取即将访问的页面topath,然后加一个useeffect,如果即将前往的页面不是当前路由自己的meta.keepalive.topath,就执行react-activation提供的clear方法
...functionindex(props){constlocation=uselocation()consttopath=props.global.topath//从dva中拿到将要访问的页面constrouteitem=keepaliveroutes.find((item)=>item.path==location.pathname)//from页面///新加代码///新加代码///新加代码useeffect(()=>{console.log('topath改变',topath)//from页面是需要keepalive的页面if(routeitem){console.log('from页面是需要keepalive的页面',routeitem)if(topath==routeitem.meta?.keepalive.topath){//所去的页面正好是当前这个路由的keepalive.topathconsole.log('所去的页面正好是当前这个路由的keepalive.topath,不做什么')}else{console.log('clear')if(alivecontroller?.clear){alivecontroller.clear()}}}},[topath])///新加代码endletdom=props.childrenif(routeitem){dom={props.children}//id一定要加否则keepalive的页面跳转另一个keepalive的页面会有问题}return( {dom}