项目背景:react项目、使用react-router、未使用redux
本次需求:希望详情页回退到列表页,列表页的状态维持之前的状态不变
想到的方案:
- 引入redux
- 使用localStorage
- react-router传参的方式
- 度娘的答案:react-keeper
每种方案的利弊:
- 由于项目从一开始就没有使用redux并且已经上线使用一段时间,我觉得这个时候添加redux实在没必要又麻烦
- 由于需要改的模块太多,localstorage需要存很多key,有点乱,第二条也待定
- react-router传参解决(列表要传参到详情,详情返回列表时需要带回参数,列表页用带回来的参数重新请求数据)
- react-keeper,是基于react-router并且对react-router的扩展,比如缓存...刚好是现在需要的功能,跃跃欲试中 0_0
下面是这次替换为react-keeper用到的,大概总结一下
真不知道我是怎么坚持改完的!!!要用react-keeper完全替换react-router
两种方式 传参、获取参数的方式都不一样,很多个模块很多个文件很多地方...现在回过头来想想,其实用redux也挺好~
友情提示: 改完之后每个模块每个功能都要仔细测一遍0.0
/* App.js */
import { BrowserRouter, Route } from 'react-keeper'
<BrowserRouter>
<div>
<Route component={Home} path='/>' /> // 这里path中的'>'和react-router中的exact大同小异
<Route component={List} path='/list>' />
<Route component={Detail} path='/list/detail' />
</div>
</BrowserRouter>
- ,keeper目前没有采用react-router中的switch、exact方案,而是类似正则$标识结束的方式,比如上面例子中path='/>'中的'>'
- 更多请参考-RouteMapping.md
/* List.js */
import { CacheLink } from 'react-keeper'
/* to只能是string,state 是 object,可以用state传参 */
<CacheLink to='/list/detail' state={{ item, id }}></CacheLink>
- 直接采用了CacheLink的方式做缓存,用state来传参。当然还有其他缓存方式,比如
<Route cache>
,这个大家可以自己研究一下 - 更多请参考-CacheLink.md
/* Detail.js */
import React from 'react'
import { Control } from 'react-keeper'
class Detail extends React.PureComponet {
componentDidMount() {
/* 其他页面可以使用Control.state获取传过来的参数 */
const { item, id } = Control.state || {}
}
onHandleClick = () => {
/* 返回上一页,也可以这样-- Control.go(path, state) */
Control.go(-1)
}
render() {
return(
<div onClick={this.onHandleClick}>取消</div>
)
}
}
- 这里采用Control.state获取参数,使用Control.go(-1)回到上一页,如果想回到上两页,参数可以是-2、-3 以此类推
- 下面是模拟出来的效果,具体表现在 — 缓存了页面滚动的位置
-
更多请参考 Control.md
缓存列表页模拟.GIF
ok!解决~~~~~~~
但事情往往要比想象的复杂很多,比如现在...,项目中有一些场景是希望既缓存当前的页数、搜索框的搜索条件,又想把详情页做的数据更改反应在列表页的数据中...
按理说这种有分页的页面是不做缓存的,不过既然这么要求了也不是不能实现,这里就react-keeper,我想到两种解决方案
1. 使用Link实现,不做缓存,跳详情页的时候将页码和搜索条件带过去,返回列表页时再将数据带回来然后再请求数据(和文章开头react-router的解决方案一样)
2. 使用CacheLink实现,列表页使用监听函数监听,详情页更改数据后将数据传回列表页,列表页监听到变化后使用setState修改某一条数据
这里只展示第二个方案(使用CacheLink实现):
/* List.js */
import { CacheLink } from 'react-keeper'
class List extends React.PureComponent {
state = {
item: [],
isModify: false
}
/* 这里用Control.history.listen函数监听数据的变化并且利用setState修改对应的值 */
componentDidMount() {
Control.history.listen((data) => {
const { item, isModify } = data.state || {}
this.setState({
item,
isModify
})
}
}
render() {
const { item, isModify } = this.state
return (
<CacheLink to='/list/detail' state={{ item, isModify }}></CacheLink>
)
}
}
-
列表页使用Control.history.listen监听数据的变化,回调函数返回的数据长下面这样
Control.history.listen回调函数返回的数据
使用心得
我觉得既然做了缓存,还要修改该页面的数据并不太适合用CacheLink,这样并不能发挥它的优势
所以我建议还是纯浏览的列表页使用CacheLink更好一些
最后决定还是把学习英语提上日程,以防某些文档只有英文版,看的那个费劲吆 - -
网友评论