react-router-cache-route icon indicating copy to clipboard operation
react-router-cache-route copied to clipboard

什么时候能够支持V6呢

Open zwmlxc opened this issue 4 years ago • 7 comments

zwmlxc avatar Nov 22 '21 13:11 zwmlxc

v6 的渲染方式好像变了,单靠 CacheRoute 不一定能把路由缓存下来,关键点转移到了 outlet 上,也就是类似现在的 Switch 上

所以,这个库不一定会继续对 v6 做支持,但也不是没有支持的方法,可以看我这个 demo,先做出简单的 keep 效果

https://github.com/CJY0208/umi4-keep-demo

CJY0208 avatar Nov 23 '21 01:11 CJY0208

好的,我看看,谢谢

zwmlxc avatar Nov 23 '21 06:11 zwmlxc

自告奋勇,推荐下自己写的这个https://github.com/liuye1296/react-keepAlive 之前v5 我也是用的作者这个库,V6之后 可以利用V6跟React 原生API 实现keepAlive 不再需要第三方库实现了

liuye1296 avatar Dec 13 '21 03:12 liuye1296

自告奋勇,推荐下自己写的这个https://github.com/liuye1296/react-keepAlive 之前v5 我也是用的作者这个库,V6之后 可以利用V6跟React 原生API 实现keepAlive 不再需要第三方库实现了

V6 是如何实现的?

wkylin avatar Apr 30 '22 08:04 wkylin

自告奋勇,推荐下自己写的这个liuye1296/react-keepAlive 之前v5 我也是用的作者这个库,V6之后 可以利用V6跟React 原生API 实现keepAlive 不再需要第三方库实现了

@wkylin 根据这位大佬提供的实现方式,简化并提取最核心的部分:

import { ReactElement, useContext, useRef } from 'react';
import { Freeze } from 'react-freeze';
import { UNSAFE_RouteContext as RouteContext } from 'react-router-dom';

function KeepAliveOutlet() {
  const caches = useRef<Record<string, ReactElement>>({});

  const matchedElement = useContext(RouteContext).outlet; // v6.3之后useOutlet会多了一层嵌套
  const matchedPath = matchedElement?.props?.value?.matches?.at(-1)?.pathname as string;

  if (matchedElement && matchedPath) {
    caches.current[matchedPath] = matchedElement;
  }

  return (
    <>
      {Object.entries(caches.current).map(([path, element]) => (
        <Freeze key={path} freeze={element !== matchedElement}>
          {element}
        </Freeze>
      ))}
    </>
  );
}

varHarrie avatar May 07 '22 09:05 varHarrie

自告奋勇,推荐下自己写的这个liuye1296/react-keepAlive 之前v5 我也是用的作者这个库,V6之后 可以利用V6跟React 原生API 实现keepAlive 不再需要第三方库实现了

@wkylin 根据这位大佬提供的实现方式,简化并提取最核心的部分:

import { ReactElement, useContext, useRef } from 'react';
import { Freeze } from 'react-freeze';
import { UNSAFE_RouteContext as RouteContext } from 'react-router-dom';

function KeepAliveOutlet() {
  const caches = useRef<Record<string, ReactElement>>({});

  const matchedElement = useContext(RouteContext).outlet; // v6.3之后useOutlet会多了一层嵌套
  const matchedPath = matchedElement?.props?.value?.matches?.at(-1)?.pathname as string;

  if (matchedElement && matchedPath) {
    caches.current[matchedPath] = matchedElement;
  }

  return (
    <>
      {Object.entries(caches.current).map(([path, element]) => (
        <Freeze key={path} freeze={element !== matchedElement}>
          {element}
        </Freeze>
      ))}
    </>
  );
}

试了下 freeze 不行,用 createPortal 实现可以

fangmd avatar Aug 05 '22 09:08 fangmd

我用到了Tabs.TabPane forceRender=true 简单的实现了一版, 可以了解一下:https://github.com/wkylin/pro-react-admin 共同学习,共同进步!

wkylin avatar Aug 05 '22 10:08 wkylin