項(xiàng)目背景:react項(xiàng)目、使用react-router、未使用redux
本次需求:希望詳情頁(yè)回退到列表頁(yè),列表頁(yè)的狀態(tài)維持之前的狀態(tài)不變
想到的方案:
- 引入redux
- 使用localStorage
- react-router傳參的方式
- 度娘的答案:react-keeper
每種方案的利弊:
- 由于項(xiàng)目從一開始就沒有使用redux并且已經(jīng)上線使用一段時(shí)間,我覺得這個(gè)時(shí)候添加redux實(shí)在沒必要又麻煩
- 由于需要改的模塊太多未玻,localstorage需要存很多key,有點(diǎn)亂胡控,第二條也待定
- react-router傳參解決(列表要傳參到詳情扳剿,詳情返回列表時(shí)需要帶回參數(shù),列表頁(yè)用帶回來的參數(shù)重新請(qǐng)求數(shù)據(jù))
- react-keeper昼激,是基于react-router并且對(duì)react-router的擴(kuò)展庇绽,比如緩存...剛好是現(xiàn)在需要的功能,躍躍欲試中 0_0
下面是這次替換為react-keeper用到的橙困,大概總結(jié)一下
真不知道我是怎么堅(jiān)持改完的G撇簟!凡傅!要用react-keeper完全替換react-router
兩種方式 傳參辟狈、獲取參數(shù)的方式都不一樣,很多個(gè)模塊很多個(gè)文件很多地方...現(xiàn)在回過頭來想想像捶,其實(shí)用redux也挺好~
友情提示: 改完之后每個(gè)模塊每個(gè)功能都要仔細(xì)測(cè)一遍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方案拓春,而是類似正則$標(biāo)識(shí)結(jié)束的方式释簿,比如上面例子中path='/>'中的'>'
- 更多請(qǐng)參考-RouteMapping.md
/* List.js */
import { CacheLink } from 'react-keeper'
/* to只能是string,state 是 object硼莽,可以用state傳參 */
<CacheLink to='/list/detail' state={{ item, id }}></CacheLink>
- 直接采用了CacheLink的方式做緩存庶溶,用state來傳參。當(dāng)然還有其他緩存方式懂鸵,比如
<Route cache>
偏螺,這個(gè)大家可以自己研究一下 - 更多請(qǐng)參考-CacheLink.md
/* Detail.js */
import React from 'react'
import { Control } from 'react-keeper'
class Detail extends React.PureComponet {
componentDidMount() {
/* 其他頁(yè)面可以使用Control.state獲取傳過來的參數(shù) */
const { item, id } = Control.state || {}
}
onHandleClick = () => {
/* 返回上一頁(yè),也可以這樣-- Control.go(path, state) */
Control.go(-1)
}
render() {
return(
<div onClick={this.onHandleClick}>取消</div>
)
}
}
- 這里采用Control.state獲取參數(shù)匆光,使用Control.go(-1)回到上一頁(yè)套像,如果想回到上兩頁(yè),參數(shù)可以是-2终息、-3 以此類推
- 下面是模擬出來的效果夺巩,具體表現(xiàn)在 — 緩存了頁(yè)面滾動(dòng)的位置
-
更多請(qǐng)參考 Control.md
緩存列表頁(yè)模擬.GIF
ok!解決~~~~~~~
但事情往往要比想象的復(fù)雜很多周崭,比如現(xiàn)在...柳譬,項(xiàng)目中有一些場(chǎng)景是希望既緩存當(dāng)前的頁(yè)數(shù)、搜索框的搜索條件续镇,又想把詳情頁(yè)做的數(shù)據(jù)更改反應(yīng)在列表頁(yè)的數(shù)據(jù)中...
按理說這種有分頁(yè)的頁(yè)面是不做緩存的美澳,不過既然這么要求了也不是不能實(shí)現(xiàn),這里就react-keeper摸航,我想到兩種解決方案
1. 使用Link實(shí)現(xiàn)制跟,不做緩存,跳詳情頁(yè)的時(shí)候?qū)㈨?yè)碼和搜索條件帶過去酱虎,返回列表頁(yè)時(shí)再將數(shù)據(jù)帶回來然后再請(qǐng)求數(shù)據(jù)(和文章開頭react-router的解決方案一樣)
2. 使用CacheLink實(shí)現(xiàn)凫岖,列表頁(yè)使用監(jiān)聽函數(shù)監(jiān)聽,詳情頁(yè)更改數(shù)據(jù)后將數(shù)據(jù)傳回列表頁(yè)逢净,列表頁(yè)監(jiān)聽到變化后使用setState修改某一條數(shù)據(jù)
這里只展示第二個(gè)方案(使用CacheLink實(shí)現(xiàn)):
/* List.js */
import { CacheLink } from 'react-keeper'
class List extends React.PureComponent {
state = {
item: [],
isModify: false
}
/* 這里用Control.history.listen函數(shù)監(jiān)聽數(shù)據(jù)的變化并且利用setState修改對(duì)應(yīng)的值 */
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>
)
}
}
-
列表頁(yè)使用Control.history.listen監(jiān)聽數(shù)據(jù)的變化哥放,回調(diào)函數(shù)返回的數(shù)據(jù)長(zhǎng)下面這樣
Control.history.listen回調(diào)函數(shù)返回的數(shù)據(jù)
使用心得
我覺得既然做了緩存,還要修改該頁(yè)面的數(shù)據(jù)并不太適合用CacheLink爹土,這樣并不能發(fā)揮它的優(yōu)勢(shì)
所以我建議還是純?yōu)g覽的列表頁(yè)使用CacheLink更好一些
最后決定還是把學(xué)習(xí)英語(yǔ)提上日程甥雕,以防某些文檔只有英文版,看的那個(gè)費(fèi)勁吆 - -