React实现组件KeepAlive的方法

1,802 阅读2分钟

使用意义

有时候我们在开发业务过程中,切换页面组件时,并不需要卸载组件,而是需要把用户交互时的数据以及状态缓存下来。我们就会需要用到KeepAlive的思想对组件加以控制。但是react并不像vue那样给我们提供封装好的keepalive组件。所以我们需要在react框架的应用基础上加以实现。

实现思路

React实现一个keepalive组件只需要注意以下两点:

1.控制组件不被销毁

2.手动控制组件的显示和隐藏

注意:以上思路是本文的核心,需要对其加以理解才能做到事半工倍。

组件会被动触发销毁时

通过路由配置,实现路由切换时页面组件不被销毁。可以通过把组件配置到children属性上,达到切换路由时,组件不被销毁,我们只需控制组件样式上的显示隐藏即可。

这里使用react-router的做法

//重新封装一个路由组件,达到缓存的效果
import {Route} from 'react-router'
const KeepAlive = (props) => {
    const { children, path } = props;
    
    //控制页面组件,路由匹配到该组件时才显示
    const ChildrenItem = (childrenProps) => {
      const { match } = childrenProps;
      return <div style={{display: match ? 'block' : 'none' }}> 
         { children } 
      <div>
    }
    
    return <Route exact {...props} children={ChildrenItem}> </Route>
} 

注册路由时,统一使用keepAlive注册组件

// router.js
import { Router } from 'react-router'

export default <Router>
   <KeepAlive path='/home'> <Home /> </KeepAlive>
    <KeepAlive path='/user'> <User /> </KeepAlive>
 </Router>

这种方法即是使用react-router的Ioc控制反转机制,把缓存组件的销毁托管给router容器,我们不需要控制组件销毁过程,只对组件不销毁的结果做控制即可。这是一种面向容器化编程的思想。

使用第三方路由库

注:点击下面标题可以查看对应使用文档

  • react-live-route

      第一次挂载到匹配位置后,当路径不匹配时,Modal 页面会被隐藏,再次匹配时会重新渲染`path`import NotLiveRoute from 'react-live-route'
      import { withRouter } from 'react-router-dom'
    
      const LiveRoute = withRouter(NotLiveRoute)
    
      <LiveRoute path="/list" alwaysLive={true} component={Modal} />
    
    
  • react-keeper

    不匹配时缓存页面状态,匹配时恢复。当然你可以配置缓存哪一个。
    
    1.  使用`cache`标签缓存页面。
    1.  打开新页面时,使用`CacheLink`组件来保存将卸载的页面。
    
     <Route cache component={Home} path='/'/>
    
     <CacheLink to='/product/ASDFADF'>Detail</CacheLink>
    
    
  • react-router-cache-route

  • react-activation

以上是本人对keepalive的理解,归根到底,目前我们都存在两种方式。第一种,缓存页面组件时,通过配置路由不被重新销毁,自主组件控制显隐。第二种,通过手动保存组件状态至不影响组件销毁的父级容器及以上的状态中。

拓展资料

如何使用Mobx的自定义Hooks

qiankun如何配置子应用keepalive

Mobx官方文档