亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React中怎么實現狀態自動保存

發布時間:2021-08-10 16:19:47 來源:億速云 閱讀:165 作者:Leah 欄目:web開發

這篇文章給大家介紹React中怎么實現狀態自動保存,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

 

什么是狀態保存?

假設有下述場景:

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

類似的數據或場景還有已填寫但未提交的表單、管理系統中可切換和可關閉的功能標簽等,這類數據隨著用戶交互逐漸變化或增長,這里理解為狀態,在交互過程中,因為某些原因需要臨時離開交互場景,則需要對狀態進行保存

在 React 中,我們通常會使用路由去管理不同的頁面,而在切換頁面時,路由將會卸載掉未匹配的頁面組件,所以上述列表頁例子中,當用戶從詳情頁退回列表頁時,會回到列表頁頂部,因為列表頁組件被路由卸載后重建了,狀態被丟失

如何實現 React 中的狀態保存

在 Vue 中,我們可以非常便捷地通過 <keep-alive>[1] 標簽實現狀態的保存,該標簽會緩存不活動的組件實例,而不是銷毀它們

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

常見的解決方式:手動保存狀態

手動保存狀態,是比較常見的解決方式,可以配合 React 組件的 componentWillUnmount 生命周期通過 redux 之類的狀態管理層對數據進行保存,通過 componentDidMount 周期進行數據恢復

在需要保存的狀態較少時,這種方式可以比較快地實現我們所需功能,但在數據量大或者情況多變時,手動保存狀態就會變成一件麻煩事了

作為程序員,當然是盡可能懶啦,為了不需要每次都關心如何對數據進行保存恢復,我們需要研究如何自動保存狀態

通過路由實現自動狀態保存(通常使用 react-router)

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

我們有以下的方式去實現這個功能

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

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

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

  完全替換掉路由方案是一個風險較大的事情,需要較為慎重地考慮3.

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

  在閱讀了 <Route> 的源碼后發現,如果使用 component 或者 render 屬性,都無法避免路由在不匹配時被卸載掉的命運

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

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

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

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

上述是最簡的調整方式,實際情況中也需要考慮隱藏狀態下 match 為 null 導致組件報錯的問題,且由于不再是組件卸載,所以和 TransitionGroup 配合得不好,導致轉場動畫難以實現

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

React中怎么實現狀態自動保存

上述探究了通過路由入手實現自動狀態保存的可能,以及現有的實現,但終究不是真實的、純粹的 KeepAlive 功能,接下來我們嘗試探究真實 KeepAlive 功能的實現

模擬真實的 <KeepAlive> 功能

以下是期望的使用方式

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

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

以下是 react-activation[8] 的實現效果

在線示例[9]

React中怎么實現狀態自動保存

關于React中怎么實現狀態自動保存就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

华坪县| 平阳县| 紫云| 曲阳县| 淳化县| 镇平县| 宝坻区| 科技| 霍邱县| 新泰市| 巴东县| 醴陵市| 安徽省| 日照市| 阿巴嘎旗| 常熟市| 皋兰县| 朝阳市| 章丘市| 清苑县| 泌阳县| 漯河市| 浠水县| 崇州市| 林口县| 格尔木市| 枣庄市| 波密县| 宜兰市| 依兰县| 德保县| 河北省| 松阳县| 惠安县| 竹溪县| 嘉禾县| 县级市| 江津市| 望城县| 无锡市| 怀仁县|