You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on May 9, 2020. It is now read-only.
问题背景
在 React 中通常会使用 react-router 去管理不同的页面切换,通过监听路由的变化匹配到对应的路由组件进行渲染,而未匹配到的组件将会被卸载, 这意味着组件被卸载之后其状态丢失。
但在某些场景下,我们希望切换路由时还能保留组件的状态不被丢失,在下次展示时进行恢复,如:
场景一:
当用户在列表页面进入详情页面后,缓存列表页面的状态,当从详情页面返回列表页面时,能恢复到上次的状态(位置状态)。
场景二:
当用户在填写表单但未提交时、可能因为某些原因需要临时离开当前页面,当从其他页面返回表单页面时,能恢复用户填写的表单信息(数据状态)。
keep-alive 简介
什么是 keep-alive?
通过 keep-alive 可以保存当前页面的数据、状态、滚动条位置及渲染内容。当切换到对应页面时,被保存的页面将直接被渲染,还原为切换前的内容。
被 keep-alive 包含的组件不会被再次初始化,也就意味着不会重走生命周期函数,但是有时候是希望我们缓存的组件可以能够再次进行渲染,因此被包含在 keep-alive 中创建的组件,通常会多出两个生命周期的钩子:
activated
与deactivated
:activated
:当 keep-alive 包含的组件再次渲染的时候触发deactivated
:当 keep-alive 包含的组件销毁的时候触发在 React 中使用 keep-alive ?
在 React 中并没有 keep-alive 的概念,该概念来源于 Vue 提供的 keep-alive 功能。因此也有人在 facebook/react/issues/12039 中询问 React 是否能支持类似 Vue keep-alive 的功能。从 issue 看没有支持的计划, Dan 给出的说法是可以通过类似
style={{display: visible ? 'block' : 'none'}}
的思路,但不认为 keep-alive 是一个好的功能,以及可能会存在内存泄漏等。但强大的 React 社区肯定不会善罢甘休,也有了相关的实现。在 React 实现 keep-alive
手动保存状态
手动保存状态即通过 React 提供的
componentWillUnmount
生命周期通过 redux 之类的状态管理库对数据进行保存,通过componentDidMount
生命周期进行数据恢复,这也是目前最常见的解决方式,这里不展开讨论。通过路由实现状态保存
由于状态丢失的主要原因是由于路由切换时导致组件被卸载,如果是这样,是否只需要保证组件不被卸载,或者在组件卸载之前将数据状态保存就可以解决我们的问题了,事实上目前社区的相关实现也正是这样。
核心思路:
路由匹配 -> 组件渲染 -> 切换路由 -> 组件卸载
=>路由匹配 -> 组件渲染 -> 切换路由 -> 组件隐藏
社区方案对比:
主要实现思路:
详见代码
在 icejs 中使用 keep-alive
TODO
小结
keep-alive 作为状态保存的一种实现方式,在某些场景如列表位置恢复,表单状态保存等非常有用,且无需重复渲染组件,是一种很好的选择。但当项目和数据复杂的情况下,需要合理使用 keep-alive 进行状态保存,以及数据的自动清理等。
相关链接:
The text was updated successfully, but these errors were encountered: