CJY0208 / react-activation

Hack <KeepAlive /> for React
https://www.npmjs.com/package/react-activation
MIT License
1.78k stars 140 forks source link

Context 重建相关问题咨询 #282

Open youngBrain1893 opened 1 year ago

youngBrain1893 commented 1 year ago
  1. 会包含不属于 KeepAlive 上传的内容 内部使用 fixedContext 维护所有已渲染过的 Context,如果页面渲染了包含 Context 的内容,那么在后续渲染 组件的时候实际 会包含 Context 的内容。 相关 DEMO

    复现流程:先访问子页面 B 刷新页面,然后切换到页面 A,可以看到页面 A 的 Keeper 渲染被包含在了页面 B 内部 Context 内

    <Route path="a">
    <PageA />
    </Route>
    <Route path="b">
    <PageB>
    <ContextForPageB />
    </PageB>
    </Route>

    image

  2. Context 重建时采用逆序的方式,可能导致原逻辑底层覆盖上层 Context 的场景失效,想问下这块逆序逻辑是基于什么情况考虑的?

  3. Context 重建逻辑是否可选可配置的方式,某些场景下遵循 内维护自身 Context,全局 Context 放到 之前实际能满足场景,重建逻辑带来了额外的复杂性,且可能有 Context 顺序变更底层值覆盖上层失败的风险

CJY0208 commented 1 year ago

问题 1:Keeper 无法得知自己可能会需要哪一个上下文,所以策略是尝试重建所有可能存在的上下文,包括实际上不是自身所需的 问题 2:逆序排布可能是设计错误,理想情况下,Keeper 重建的上下文应按照原上下文的排布方式,目前还没有收录到因为逆序而产生的问题,有时间我会检查一下 问题 3:是在说问题 2 吗,理想情况下这块不需要给开发者暴露额外的配置,最好是 keep alive 自行处理,开发者无感,不过可以考虑暴露配置属性,指定要修复的上下文,这样可以节约 keepalive 自行处理而导致的无效性能消耗

youngBrain1893 commented 1 year ago

问题 3 可能没表述清楚 如问题 1,2 在复写了所有可能存在的 context 上下文的情况下一方面会带来性能的开销(ConsumerWrap, ProviderBridege),最重要的还是存在 context 错误的问题

<AProvider value={outer}>
    <AProvider value={inner}> // 覆盖 outer 值
      <KeepAlive>
         {/* bizContent */}
      </KeepAlive>
    </AProvider>
</AProvider>

这里 bizContent 预期拿到上下文应该是 inner,实际重建会拿到 outer 的值

但是实际业务使用中,比如我这边希望在路由系统内使用,每个子页面由 KeepAlive 包裹,全局相关上下文提到 之前,直接使用 react 的原始上下文实际已经能满足我的述求,此时如果可以不重建上下文,一方面可减少不必要的性能开销,另一方面也避免了原 Context 和 ProviderBridge 数据同步的性能开销和生命周期流程处理的差异

<SomeGlobalProvider> // 全局上下文
    <AliveScope>
        <HashRoute>
          <Route>
            <PageA path="A">
              <SomeInnerProvider> // 页面局部上下文
              </SomeInnerProvider>
            </PageA>
          </Router>
        </HashRoute>
    </AliveScope>
</SomeGlobalProvider>