React中怎么實(shí)現(xiàn)狀態(tài)自動(dòng)保存

這篇文章給大家介紹React中怎么實(shí)現(xiàn)狀態(tài)自動(dòng)保存,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

成都創(chuàng)新互聯(lián)專注于福清企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城網(wǎng)站建設(shè)。福清網(wǎng)站建設(shè)公司,為福清等地區(qū)提供建站服務(wù)。全流程按需策劃,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

 

什么是狀態(tài)保存?

假設(shè)有下述場景:

移動(dòng)端中,用戶訪問了一個(gè)列表頁,上拉瀏覽列表頁的過程中,隨著滾動(dòng)高度逐漸增加,數(shù)據(jù)也將采用觸底分頁加載的形式逐步增加,列表頁瀏覽到某個(gè)位置,用戶看到了感興趣的項(xiàng)目,點(diǎn)擊查看其詳情,進(jìn)入詳情頁,從詳情頁退回列表頁時(shí),需要停留在離開列表頁時(shí)的瀏覽位置上

類似的數(shù)據(jù)或場景還有已填寫但未提交的表單、管理系統(tǒng)中可切換和可關(guān)閉的功能標(biāo)簽等,這類數(shù)據(jù)隨著用戶交互逐漸變化或增長,這里理解為狀態(tài),在交互過程中,因?yàn)槟承┰蛐枰R時(shí)離開交互場景,則需要對狀態(tài)進(jìn)行保存

在 React 中,我們通常會(huì)使用路由去管理不同的頁面,而在切換頁面時(shí),路由將會(huì)卸載掉未匹配的頁面組件,所以上述列表頁例子中,當(dāng)用戶從詳情頁退回列表頁時(shí),會(huì)回到列表頁頂部,因?yàn)榱斜眄摻M件被路由卸載后重建了,狀態(tài)被丟失

如何實(shí)現(xiàn) React 中的狀態(tài)保存

在 Vue 中,我們可以非常便捷地通過 <keep-alive>[1] 標(biāo)簽實(shí)現(xiàn)狀態(tài)的保存,該標(biāo)簽會(huì)緩存不活動(dòng)的組件實(shí)例,而不是銷毀它們

而在 React 中并沒有這個(gè)功能,曾經(jīng)有人在官方提過功能 issues[2] ,但官方認(rèn)為這個(gè)功能容易造成內(nèi)存泄露,表示暫時(shí)不考慮支持,所以我們需要自己想辦法了

常見的解決方式:手動(dòng)保存狀態(tài)

手動(dòng)保存狀態(tài),是比較常見的解決方式,可以配合 React 組件的 componentWillUnmount 生命周期通過 redux 之類的狀態(tài)管理層對數(shù)據(jù)進(jìn)行保存,通過 componentDidMount 周期進(jìn)行數(shù)據(jù)恢復(fù)

在需要保存的狀態(tài)較少時(shí),這種方式可以比較快地實(shí)現(xiàn)我們所需功能,但在數(shù)據(jù)量大或者情況多變時(shí),手動(dòng)保存狀態(tài)就會(huì)變成一件麻煩事了

作為程序員,當(dāng)然是盡可能懶啦,為了不需要每次都關(guān)心如何對數(shù)據(jù)進(jìn)行保存恢復(fù),我們需要研究如何自動(dòng)保存狀態(tài)

通過路由實(shí)現(xiàn)自動(dòng)狀態(tài)保存(通常使用 react-router)

既然 React 中狀態(tài)的丟失是由于路由切換時(shí)卸載了組件引起的,那可以嘗試從路由機(jī)制上去入手,改變路由對組件的渲染行為

我們有以下的方式去實(shí)現(xiàn)這個(gè)功能

  1.  重寫 <Route> 組件,可參考 react-live-route[4]

  重寫可以實(shí)現(xiàn)我們想要的功能,但成本也比較高,需要注意對原始 <Route> 功能的保存,以及多個(gè) react-router 版本的兼容

    2.  替換路由庫為 react-keeper[5]

  完全替換掉路由方案是一個(gè)風(fēng)險(xiǎn)較大的事情,需要較為慎重地考慮3.

  3.  基于 <Route> 組件現(xiàn)有行為做拓展,可參考 react-router-cache-route[6]

  在閱讀了 <Route> 的源碼后發(fā)現(xiàn),如果使用 component 或者 render 屬性,都無法避免路由在不匹配時(shí)被卸載掉的命運(yùn)

  但將 children 屬性當(dāng)作方法來使用,我們就有手動(dòng)控制渲染的行為的可能,關(guān)鍵代碼在此處 https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Route.js#L41-L72

// 節(jié)選自 Route 組件中的 render 函數(shù)  if (typeof children === "function") {       childrenchildren = children(props); // children 是函數(shù)時(shí),將對 children 進(jìn)行調(diào)用得到真實(shí)的渲染結(jié)果  if (children === undefined) {         ...         children = null;       }     }  return (  <RouterContext.Provider value={props}>         {children && !isEmptyChildren(children) // children 存在時(shí),將使用 children 進(jìn)行渲染           ? children           : props.match             ? component               ? React.createElement(component, props)               : render                 ? render(props)                 : null // 使用 render 屬性無法阻止組件的卸載             : null // 使用 component 屬性無法阻止組件的卸載         }  </RouterContext.Provider>     );

基于上述源碼探究,我們可以對 <Route> 進(jìn)行拓展,將 <Route> 的不匹配行為由卸載調(diào)整為隱藏,如下

<Route exact path="/list">       {props => (           <div style={props.match ? null : { display: 'none' }}>               <List {...props} />           </div>       )}   </Route>

上述是最簡的調(diào)整方式,實(shí)際情況中也需要考慮隱藏狀態(tài)下 match 為 null 導(dǎo)致組件報(bào)錯(cuò)的問題,且由于不再是組件卸載,所以和 TransitionGroup 配合得不好,導(dǎo)致轉(zhuǎn)場動(dòng)畫難以實(shí)現(xiàn)

使用 react-router-cache-route[7],得到的效果大致如下圖,

React中怎么實(shí)現(xiàn)狀態(tài)自動(dòng)保存

上述探究了通過路由入手實(shí)現(xiàn)自動(dòng)狀態(tài)保存的可能,以及現(xiàn)有的實(shí)現(xiàn),但終究不是真實(shí)的、純粹的 KeepAlive 功能,接下來我們嘗試探究真實(shí) KeepAlive 功能的實(shí)現(xiàn)

模擬真實(shí)的 <KeepAlive> 功能

以下是期望的使用方式

function App() {  const [show, setShow] = useState(true)  return (  <div>  <button onClick={() => setShow(show => !show)}>Toggle</button>        {show && (  <KeepAlive>  <Test />  </KeepAlive>        )}  </div>    )  }

實(shí)現(xiàn)原理說起來較為簡單,由于 React 會(huì)卸載掉處于固有組件層級內(nèi)的組件,所以我們需要將 <KeepAlive> 中的組件,也就是其 children 屬性抽取出來,渲染到一個(gè)不會(huì)被卸載的組件內(nèi),就可以實(shí)現(xiàn)此功能

以下是 react-activation[8] 的實(shí)現(xiàn)效果

在線示例[9]

React中怎么實(shí)現(xiàn)狀態(tài)自動(dòng)保存

關(guān)于React中怎么實(shí)現(xiàn)狀態(tài)自動(dòng)保存就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

當(dāng)前標(biāo)題:React中怎么實(shí)現(xiàn)狀態(tài)自動(dòng)保存
文章網(wǎng)址:http://muchs.cn/article42/ijdpec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)營銷型網(wǎng)站建設(shè)、網(wǎng)站營銷、標(biāo)簽優(yōu)化、自適應(yīng)網(wǎng)站、網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)