Wendao

Results 42 comments of Wendao

主要是考虑到这个库的实现更接近于可能的官方实现,而不是像react- activation那种重度hack,有一点小瑕疵,只要能通过其他方式来弥补,也没啥问题。 实现思路还是很值得学习的,加油.

上述问题是在umi4 react18 react-router6下表现的,今天在umi3上测试了一下(umi3用的是react17.x react-router5),切换页面虽然没有display: none,但有别的问题: ![image](https://user-images.githubusercontent.com/25472851/189060818-5ab3ee98-3343-44d0-b866-306669badef4.png) ![image](https://user-images.githubusercontent.com/25472851/189060992-eac4bc1b-1482-486b-93f6-cff9ccffa3d2.png) 在进行路由切换的时候,会导致这个组件已卸载但还是执行setV导致的报错,当页面且回来之后,fiber节点可能还记录了卸载之后的setV操作(在已经切换之后记录的),这就导致还原的fiber节点和实际fiber不一致,导致setV反复执行,5,6,5,6这种结果. 这种边缘情况,以上,虽然在umi3中,针对这种情况也可以用ref或者变量截断的方式来避免出现。 用来复现的代码 ```tsx import { useEffect, useState } from 'react' import { keepAlive } from 'react-fiber-keep-alive' const Index = () => {...

观察了一下,发现在umi3中出现上述问题的原因可能是useEffect在组件卸载时,KeepAlive拿这个组件的fiber信息存入内存,然后卸载,但是fiber信息在存入内存之后还执行了一次timer,但是这个时候组件其实unmoumted了,就会报这个错。 不理解的是(相关逻辑细节),为什么还原的时候会出现反复setV。

发现了华点,来回切换路由之后,竟然出现了切到别的页面,定时器未卸载,还一直在执行的情况: ```tsx import { useEffect, useState } from 'react' import { keepAlive } from 'react-fiber-keep-alive' const Index = () => { const [v, setV] = useState(0); console.log(v); useEffect(() => {...

codesanbox真鸡儿难用,搞了半天写一点代码编译半天,换github demo了: https://github.com/MatrixAge/codesandbox 总体上umi4用keepAlive是能用的,解决那个display: none就行了,umi3上是完全不可用的。

> umi 4 因该是使用了 React-18 的 `` 组件 会执行 hideInstance() 操作加上 `display: none` https://github.com/facebook/react/blob/v18.2.0/packages/react-dom/src/client/ReactDOMHostConfig.js#L636 与umi4 和 react-router都没关系,是react18自己执行的hideInstance( instance ): ![image](https://user-images.githubusercontent.com/25472851/189078737-b70194d5-7bac-4b66-a0c6-ad0bae4d8bd0.png)

https://github.com/facebook/react/blob/c8b778b7f44faba63d1d2eeb9f7d95da282e0a34/packages/react-reconciler/README.md#hideinstanceinstance 这个方法竟然是react-reconciler提供的,感觉可以直接引入react-reconciler,如果获取到是react18,使用react-reconciler的hideInstance等方法去维护需要被keepAlive的节点。

https://github.com/facebook/react/blob/4ea064eb0915b355b584bff376e90dbae0e8b169/packages/react-reconciler/src/ReactFiberOffscreenComponent.js 看了一下官方的代码,他们正在实现这部分的功能,说不定在18.3就能看到了。

搞了一个hooks用来弥补一些不足,针对react18+场景下的可使用方案: ```ts import { useScroll } from 'ahooks' import { useEffect, useRef } from 'react' import { markEffectHookIsOnetime } from 'react-fiber-keep-alive' export default () => { const el = useRef(null)...