從資料較多的列表頁進入詳情頁返回時,列表頁恢復原來的狀態。
需求:
從一個橫向縱向都有滾動條的列表頁進入詳情頁,返回時列表頁的活動條恢復到之前到位置。
難點:
1.列表用的是antd的table元件,滾動條是這個table元件的,瀏覽器返回時自身可以記錄頁面即document的滾動條,但不能記錄某一個元素的滾動條。
2.資料載入,每次進去列表頁時資料都會重新載入,列表的初始值都為空,表頭也需要動態載入,所以返回頁面時,整個列表是沒有高度和寬度的,所以即使設一個初始的滾動條位置也不會生效。
解決方案:
1. 設定列表資料初值
在離開列表頁時將載入列表相關的資料儲存到本地,或者放到redux裡,返回頁面時可以直接取值,列表不會沒有寬高。在列表頁初始化時即constructor 時就可以將存下來的資料取出賦值。
2.設定列表滾動條位置初值
審查列表頁渲染以後的節點,找到滾動條所對應的元素,並將其作為目標元素操作dom。
離開頁面時記錄滾動條的位置,在生命週期didmount 裡操作dom設定滾動條的初始位置。
離開頁面時可以是componentWillUnmount或者是頁面跳轉前。
操作dom時用原生js的方法和ReactDom得ReactDom.FindDOMNode方法結合。
部分程式碼:
componentDidMount() {
var Btn = document.getElementsByClassName('ant-table-body')[0]
const scrollLeft = localDb.get('scrollLeft') || 0;
const scrollTop = localDb.get('scrollTop') || 0;
// 設定滾動條的位置
ReactDOM.findDOMNode(Btn).scrollTo(scrollLeft, scrollTop);
let params = {}
const { initDate } = this.state
params.beginDate = initDate[0]
params.endDate = initDate[1]
this.loadData(params)
}
componentWillUnmount() {
// 通過審查元素找到滾動條的盒子元素類
const scrollLeft = document.getElementsByClassName('ant-table-body')[0].scrollLeft;
const scrollTop = document.getElementsByClassName('ant-table-body')[0].scrollTop;
const {
wid,
checkedUUids,
org,
data,
type
} = this.state
localDb.set('scrollLeft', scrollLeft);
localDb.set('scrollTop', scrollTop);
}
複製程式碼
後記
今天一個朋友問我要怎麼react後退不重新整理時,我告訴他了我的這種實現方式,不難但是複雜。一直以來用vue開發的他,發出了這麼一聲感嘆,然後告訴我vue只要在元件外包一層keep-alive就可以記錄元件的狀態了,呃真的真的是灰常簡單啊。