react 页面缓存(记录表单内容、滚动条位置等)

2,358 阅读3分钟
1、使用redux等状态管理器进行保存(适合保存一些简单状态 eg.滚动条位置、分页的页码、简单的表单信息)
2、使用css对需要缓存的页面进行手动展示和隐藏
3、最愉快的方式就是用别人造好的轮子了,每天都是代码的搬运工嘿嘿 react-router-cache-route
  • 下载依赖 npm install react-router-cache-route --save or yarn add react-router-cache-route
  • 使用
仅供参考
react 版本 '16.8.6'
react-router 版本 '^5.0.0'

使用的过程中一直不生效,千万注意CacheRoute需要直接使用,不能再进行包裹封装了哦 不然就会吐槽这玩意儿千万遍也实现不了需求。若需要权限校验等需要直接在使用到CacheRoute的地方进行判断校验。

import React from 'react'
import { HashRouter as Router, Route } from 'react-router-dom'
import CacheRoute, { CacheSwitch } from 'react-router-cache-route'

import List from './views/List'
import Item from './views/Item'

const App = () => (
  <Router>
    <CacheSwitch>
      <CacheRoute exact path="/list" component={List} />
      <Route exact path="/item/:id" component={Item} />
      <Route render={() => <div>404 Not Found</div>} />
    </CacheSwitch>
  </Router>
)

export default App

👆上面的当然是官网的使用方式了,由于有部分页面不需要进行缓存,就自己设了张路由表,简单的不能再简单的玩意儿哈

/**
 * 路由配置文件 routes.js
 */
 
import React from 'react';
import { WomanOutlined, CompassFilled, BarsOutlined } from '@ant-design/icons';
import LoadableComponent from './components/common/LoadableComponent'; // 这里用了react-lodable 也可以直接用lazy哈

const routes = [
    {
      title: '首页',// 侧边栏title/顶部tab菜单title
      icon: <CompassFilled />,// 侧边栏icon
      key: '/home/data',// 路由
      component: LoadableComponent(() => import('./views/Home')),// 页面组件
      exact: true,// 是否全匹配
      cache: true,// 是否需要缓存页面
      saveScrollPosition: true, // 是否需要缓存页面位置
      whenCache: 'always', // 缓存时机
    },
    {
      title: '商品列表',
      icon: <WomanOutlined />,
      key: '/home/product',
      component: LoadableComponent(() => import('./views/Product')),
      exact: true,
      cache: true,
      saveScrollPosition: false,
      whenCache: 'always', 
    },
    {
      title: '用户列表',
      icon: <BarsOutlined />,
      key: '/home/user',
      component: LoadableComponent(() => import('./views/User')),
      exact: true,
      cache: true,
      saveScrollPosition: true,
      whenCache: 'always', 
    },
    
]

终于到使用的地方喽


import React from 'react'
import { withRouter, Switch } from 'react-router-dom'
import CacheRoute, { CacheSwitch } from 'react-router-cache-route';
import { compose } from 'redux';
import routes from '../../../routes';
const cacheRoutes = []; // 需要缓存的页面路由
const routers = [];

function getRoutes(routes) {
  routes.forEach(item => {
    if (item.component && !item.cache) {
      routers.push(item)
    } else if (item.component && item.cache) {
      cacheRoutes.push(item)
    } else if (item.subs) {
      getRoutes(item.subs)
    }
  })
}

class Index extends React.Component {
  render() {
    return (
    <Router>
      <CacheSwitch>
         // 这里自己实际使用的时候多封装了一层权限的判断
        {routers.map(item => (<Route exact={item.exact} path={item.key} component={item.component} key={item.key} />))}
         // 和权限相关的判断操作就搁这外头直接写吧
        {cacheRoutes.map(item => (<CacheRoute exact={item.exact} saveScrollPosition path={item.key} component={item.component} key={item.key} when={item.whenCache || 'always'} />))}
      </CacheSwitch>
      </Router>
    )
  }
}

export default compose(
  withRouter,
)(Index);

到这里页面就愉快的缓存好了

  • 莫急莫急到这里还不能算真正的结束,万一页面我只想缓存部分内容,其余部分内容我又需要页面返回的时候能更新该咋整,不要想太多,首先以最快的速度打开官网看看有没有‘灵感’

不难发现,作者考虑的比我们更加完善,已经给出了两个独有的生命周期函数

import { useDidCache, useDidRecover } from 'react-router-cache-route'

export default function List() {

    // 被缓存时
  useDidCache(() => {
    console.log('List cached 1')
  })

    //被恢复时 假如我想返回已经被缓存页面的同时更新改页面的某些数据(eg.新增后返回到列表页)就可以在这操作一番
  useDidRecover(() => {
    console.log('List recovered')
  })

  return (
    // ...
  )
}