react-router v6 缓存方案

1,753 阅读1分钟

摘要

SPA 应用经常需要使用缓存前一页的内容,例如:列表页 -> 详情页

这篇文章关注如何缓存列表页

此处不谈论 mobx, redux 等常见数据管理方案

方案

结合 useRoutes useOutlet 实现缓存

关键的是利用 Outlet 判断是否渲染了 Detail 页面,从而缓存 List

withCache.js

// Freeze 是利用 Suspense 把组件 display: none; 了而已
import { Freeze } from 'react-freeze'
export const Cache = (props) => {
  // useOutlet 会返回匹配到的下级页面,如果 element !== null,那说明访问到了 Detail 页面, List 就可以收起来了
  const element = useOutlet()
  const freeze = !!element
  return (
    <>
      <Freeze freeze={freeze}>{props.children}</Freeze>
      {element}
    </>
  )
}

export function withCache(Component) {
  return (props) => (
    <Cache>
      <Component {...props} />
    </Cache>
  )
}

App.js

import List from './List'
import Detail from './Detail'
import { withCache } from './withCache'

// 将 List 用 Cache 包裹一下
const CacheAbleList = withCache(List)

const App = () => {
  const element = useRoutes([
    {
      path: '/list',
      element: <CacheAbleList />,
      children: [{ path: ':id', element: <Detail /> }],
    },
  ])

  return element
}