shenjunru / react-fiber-keep-alive

A component that maintains component state and avoids repeated re-rendering.
MIT License
60 stars 1 forks source link

功能需求:增加 activated/deactivated 相关的生命周期 #10

Closed promise96319 closed 1 year ago

promise96319 commented 1 year ago

问题:目前的 KeepAlive 组件即使能拿到缓存的 fiber 渲染,也会触发子组件的 mount 生命周期。这就导致一些在 mount 生命周期里执行的事件会触发,比如请求服务端数据,设置一些其他的数据状态等。

建议:需要增加类似 Vue 的 activated/deactivated 生命周期,在有缓存的时候应该不触发 mount 而是触发 activated。

shenjunru commented 1 year ago

请使用 markEffectHookIsOnetime() 标记,readme 有说明

promise96319 commented 1 year ago

好的谢谢~,没注意到这个api。

再请教一个问题,markEffectHookIsOnetime 只是限定了 mount 执行一次,那如果我想保存组件或者页面的滚动距离 scrollTop,下次使用缓存的时候恢复之前的滚动距离,对 dom 元素设置 scrollTop,似乎没有类似于 activated 的钩子去做这个设置操作。

shenjunru commented 1 year ago

没有特定的 api 对应 activated dom 本身会保留滚动的状态,正常情况下,重新 attach 到 dom 树上后,会还原之前的滚动位置

shenjunru commented 1 year ago

activated 后会重新执行正常的 react 生命周期

这也是为什么有这些 api

shenjunru commented 1 year ago

如果 hook 的 dependency 变化了,即便加了 markEffectHookIsOnetime,hook 还是会重新执行。

laoxubuer commented 8 months ago

activated 后会重新执行正常的 react 生命周期

这也是为什么有这些 api

  • markEffectHookIsOnetime
  • markClassComponentHasSideEffectRender

第三方组件内部的副作用似乎除了手动缓存,没有很好的解决方案。比如 ProComponents 的很多组件都支持绑定一个返回Promise的方法到request,业务代码无法直接对其进行干涉, 要么手动缓存请求数据,重新mount的时候 return 上次获取的数据

<ProTable<GithubIssueItem>
     // ...
      request={async (params, sort, filter) => {
        console.log(sort, filter);
        await waitTime(2000);
        return request<{
          data: GithubIssueItem[];
        }>('https://proapi.azurewebsites.net/github/issues', {
          params,
        });
      }}
    />