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 的Button使用,Button会自动出现Loading状态 #225

Closed
waterJLuck opened this issue Sep 22, 2022 · 13 comments
Closed

配合antd 的Button使用,Button会自动出现Loading状态 #225

waterJLuck opened this issue Sep 22, 2022 · 13 comments

Comments

@waterJLuck
Copy link

1
在线地址:https://codesandbox.io/p/github/waterJLuck/antd-activation/draft/lucid-tdd?import=true&file=%2Fsrc%2Fview%2Fpage1.tsx

复现方法: 点击增加按钮 一秒后再点击去page2按钮

@CJY0208
Copy link
Owner

CJY0208 commented Sep 26, 2022

这个问题确实挺离奇的,我看看

@Cool-Star
Copy link

Cool-Star commented Sep 29, 2022

不仅仅是Button。
Dropdown ToolTip 等节点挂载在body的组件,切换回会出现先短暂显示再隐藏的效果。

@chenhb23
Copy link

chenhb23 commented Nov 8, 2022

React 版本降到 17 就好了

@GitHub-WF
Copy link

同样的问题,有一部分状态没有缓存

@CJY0208
Copy link
Owner

CJY0208 commented Nov 9, 2022

跟进到可能与 ReactDOMClient.createRoot 有关,换成传统的 ReactDOM.render 问题就消失了

具体表现为,useLayoutEffect 在 createRoot 下,会随着组件重新激活而执行多次,比较怪异,render 下没有这个问题

@CJY0208
Copy link
Owner

CJY0208 commented Nov 10, 2022

react 官方目前记录了类似的问题
facebook/react#25511

@CJY0208
Copy link
Owner

CJY0208 commented Nov 11, 2022

最终确认是 react-freeze 库与 ReactDOMClient.createRoot 搭配使用时会造成 React.useLayoutEffect 多次重复执行,而 antd 底层的 rc-motion 动画库依赖了 useLayoutEffect,导致了使用了该库的 Loading 图标被异常激活,理论上所有使用 rc-motion 的部分都有这个问题

已经给 react-freeze 提了 issue,但不确定这块有方式解决
software-mansion/react-freeze#29

目前的解决方案:

  1. 不使用 createRoot,而是使用 ReactDOM.render,可能会不兼容后续部分 React 本身的更新(用户侧的调整)
  2. 不使用 react-freeze,会导致缓存的性能下降(需要 react-activation 更新支关闭 freeze 功能)

相关问题重现

Open in StackBlitz
test

@CJY0208
Copy link
Owner

CJY0208 commented Nov 17, 2022

react-activation 发布了 0.12.2 支持通过 autoFreeze={false} 关闭 freeze 功能,关闭后不会再出现 loading,但缓存性能会有所下降

@CJY0208 CJY0208 closed this as completed Nov 17, 2022
@Cool-Star
Copy link

我目前的解决方案是关闭antd组件的动画过渡效果,这个api在antd官方文档上并没有提及,但实际上是可以透传给底层rc组件生效的。

@shangwanzheng
Copy link

我目前的解决方案是关闭antd组件的动画过渡效果,这个api在antd官方文档上并没有提及,但实际上是可以透传给底层rc组件生效的。

这个有具体文档么

@4innocent
Copy link

react 18最大的更新就是concurrent,用ReactDOM.render就退回legacy了,那18的意义就没了。所以,如果你的项目用了react 18还是建议使用ReactDOMClient.createRoot的,可以用这种方式避免出现loading:

// 给icon传空的Fragment,这里loading不要传true,可以不传,或者传false,具体可以看iconNode
<Button icon={<></>}><Button>

如果不给icon传值的话,antd就会使用默认的LoadingIcon,具体可以看iconNode,LoadingIcon存在就会去执行CSSMotion,Motion这个库好久没更新,没往下追了。所以,传空的fragment覆盖掉默认的LoadingIcon,就不会执行CSSMotion里面的逻辑,自然也就没有loading了。


至于@CJY0208给的例子,react-freeze用了Suspense,在react18和react17中Suspense有不同的行为,在react 18中Suspense的resolve是会触发useLayoutEffect的,严格来说应该是更符合直觉上的lifecycle了。具体可以看reactwg/react-18#7
另外,在suspense里面,ref行为也有点改变,不知道有没有影响。

@chengdick
Copy link

chengdick commented Apr 3, 2023

发现新问题,如果用createRoot 这个方法发现,pro-table组建加载会导致路由缓慢,卡顿,还是感觉用autoFreeze好点

@evelope
Copy link

evelope commented May 24, 2024

使用 autoFreeze={false} , 页面第一次切换不会缓存,第二次才会缓存。
比如刚打开的是A, 跳转到B,再返回A,发现A没有缓存。
然后再次 跳转到B,再返回A,这时候A是缓存的。

又试了一下,A页面的组件状态缓存了(比如输入框输的值), 但是 useEffEct 第一次还是会触发。

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

9 participants