Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

antd pro v5 umi4 在app.tsx 中如何获取 route #62

Open
oneHelloGit opened this issue Nov 24, 2023 · 27 comments
Open

antd pro v5 umi4 在app.tsx 中如何获取 route #62

oneHelloGit opened this issue Nov 24, 2023 · 27 comments

Comments

@oneHelloGit
Copy link

在自己antd pro v5 umi4项目中 按照作者的方式,在app.tsx中不知道如何获取route,childrenRender方法的第二个参数也无法获取到数据,希望可以指点,感谢
image

@yunsii
Copy link
Owner

yunsii commented Nov 24, 2023

Umi4 已经使用 React Router 6 了,不存在获取不到 route 的问题,直接 useOutlet 还是啥就能拿到当前路由组件了,另外上次看到说 ant design pro 不是说官方就支持多标签页了吗?这个周末我跟进下现在什么情况了。

@yunsii
Copy link
Owner

yunsii commented Nov 26, 2023

这周也不行了,下周我会具体研究下这拖延很久了的怎么在 Ant Design Pro 5 和 Umi 4 下的实现多标签页,毕竟现在基本不用 Umi 了,得专门抽空处理下 😂

@yunsii
Copy link
Owner

yunsii commented Dec 10, 2023

@oneHelloGit 刚研究了一下,光是结合 React Router v6 来做得使用 useRoutes 来封装,也能搜到相关中文文章。在 Umi 封装下直接使用 useRoutes 会报错(通过 useAppData 拿到 clientRoutes),且现在 Ant Design Pro v6 内部有个 tabsLayout 的配置,我测试了没有作用。理想情况下是等 React / React Router 原生支持 Offscreen,但是目前看来遥遥无期

之后会先研究下在 React Router v6 的直接实现,合适的话再 PR 到 Umi 生态吧 😂

@yunsii
Copy link
Owner

yunsii commented Apr 5, 2024

关联一下,目前的 umi + React Router v6 封装下是做不了的。

@cdx111
Copy link

cdx111 commented May 27, 2024

用Suspense配合useEffectLayout就可以实现offscreen或keep-live的效果,我已经在项目里面使用很长时间没有什么问题

@yunsii
Copy link
Owner

yunsii commented May 27, 2024

@cdx111 Suspense + useLayoutEffect 是怎么跟 Offscreen 扯上关系的?👀

@cdx111
Copy link

cdx111 commented May 27, 2024

@cdx111 Suspense + useLayoutEffect 是怎么跟 Offscreen 扯上关系的?👀

Suspense再次suspend会保存children,再次显示会调用useEffectLayout,那么就可以利用这个做keep-live

@cdx111
Copy link

cdx111 commented May 27, 2024

If React needs to hide the already visible content because it suspended again, it will clean up layout Effects in the content tree. When the content is ready to be shown again, React will fire the layout Effects again. This ensures that Effects measuring the DOM layout don’t try to do this while the content is hidden.

@yunsii
Copy link
Owner

yunsii commented May 27, 2024

有点骚操作的意思哦,不过看起来是不是得完全自己控制该渲染哪个页面组件?

@cdx111
Copy link

cdx111 commented May 28, 2024

有点骚操作的意思哦,不过看起来是不是得完全自己控制该渲染哪个页面组件?

你可以看看这个#62 (comment) 同样的思路

@cdx111
Copy link

cdx111 commented May 28, 2024

@cdx111
Copy link

cdx111 commented May 28, 2024

If React needs to hide the already visible content because it suspended again这里是hide而不是unmount

@cdx111
Copy link

cdx111 commented May 28, 2024

然后配合useEffectLayout可以知道页面再次显示

@yunsii
Copy link
Owner

yunsii commented May 28, 2024

实现思路不一样吧,我之前的思路是缓存 Switch,直接通过路由跳转就可以切换了,到 React Router 6 我也想沿用这个思路。如果自行控制渲染组件的话,什么做法都可以了 😂

@cdx111
Copy link

cdx111 commented May 28, 2024

实现思路不一样吧,我之前的思路是缓存 Switch,直接通过路由跳转就可以切换了,到 React Router 6 我也想沿用这个思路。如果自行控制渲染组件的话,什么做法都可以了 😂

一样啊,我也是配合router来的

@yunsii
Copy link
Owner

yunsii commented May 28, 2024

那 React Router 6 之后不是只能通过 useOutlet 拿到当前的页面组件了吗?我记得之前我看过源码,这个 hook 内部直接使用了 context,路由一改 outlet 就变了,没发缓存的。你是直接用的路由组件?

@cdx111
Copy link

cdx111 commented May 28, 2024

那 React Router 6 之后不是只能通过 useOutlet 拿到当前的页面组件了吗?我记得之前我看过源码,这个 hook 内部直接使用了 context,路由一改 outlet 就变了,没发缓存的。你是直接用的路由组件?

这样使用{outlet},只要offScreen没有被卸载,outlet怎么变化都被缓存,可以判断哪些路径不需要缓存就不要放在offscreen作为它的children

@cdx111
Copy link

cdx111 commented May 28, 2024

image

@yunsii
Copy link
Owner

yunsii commented May 28, 2024

这样看起来不会所有缓存的 outlet 都会被渲染成同一个页面吗?也就是状态能够缓存吗?👀

@cdx111
Copy link

cdx111 commented May 28, 2024

不同页面的,因为pathname变化了outlet也变化了

@cdx111
Copy link

cdx111 commented May 28, 2024

我现在已经用vue了,react越来越远

@yunsii
Copy link
Owner

yunsii commented May 28, 2024

那你说的这个方案状态都丢失了显然是不够合理的 😂 还是得等等官方的离屏渲染。我个人还是更喜欢 React 开发的,Vue 用不惯

@cdx111
Copy link

cdx111 commented May 28, 2024

那你说的这个方案状态都丢失了显然是不够合理的 😂 还是得等等官方的离屏渲染。我个人还是更喜欢 React 开发的,Vue 用不惯

我说那个方案状态是不会丢失的

@yunsii
Copy link
Owner

yunsii commented May 28, 2024

这么神奇的吗?那我有机会好好学习下这个的原理 🫡

@cdx111
Copy link

cdx111 commented May 28, 2024

原理很简单就是利用Suspense这个组件的机制,If React needs to hide the already visible content, 只要在Suspence的子组件throw 一个promise就会再次进入suspend,那样react就会hide已经渲染的内容而不是卸载。卸载意味着状态丢失。

@cdx111
Copy link

cdx111 commented May 28, 2024

你看看我封装的,你就知道了

import { Suspense, useEffect, useRef } from "react";

function Prepare(props: { mode: 'hidden' | 'visible'; children: any }) {
  const { mode, children } = props;
  
  const resolveRef = useRef<any>();

  const resolvePromise = () => {
    if (typeof resolveRef.current === 'function') {
      resolveRef.current();
      resolveRef.current = null
    }
  };

  resolvePromise();
 
  useEffect(() => resolvePromise, []);
  if (mode === 'hidden') {
    throw new Promise<void>((resolve) => {
      resolveRef.current = resolve
    });
  }
  return <>{children}</>;
}

export function OffScreen(props: { mode: 'hidden' | 'visible'; children: any }) {
  return (
    <Suspense>
      <Prepare {...props}></Prepare>
    </Suspense>
  );
}

export default OffScreen

@yunsii
Copy link
Owner

yunsii commented May 28, 2024

有点东西,还不知道 Suspense 还有这种骚操作呢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants