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

CustomWrapper 嵌套使用后失效 #10872

Closed
CS-Tao opened this issue Dec 9, 2021 · 4 comments · Fixed by #10873
Closed

CustomWrapper 嵌套使用后失效 #10872

CS-Tao opened this issue Dec 9, 2021 · 4 comments · Fixed by #10873
Labels
F-react Framework - React T-tt Target - 编译到字节跳动小程序 V-3 Version - 3.x

Comments

@CS-Tao
Copy link
Contributor

CS-Tao commented Dec 9, 2021

相关平台

字节跳动小程序

复现仓库

https://github.com/CS-Tao/taro3-nested-custom-wrapper-demo
小程序基础库: 1.0.0.598
使用框架: React

复现步骤

Demo: https://github.com/CS-Tao/taro3-nested-custom-wrapper-demo

页面结构

<View>
  <CustomWrapper>
    <Demo>Only One Custom Wrapper</Demo>
  </CustomWrapper>
  <CustomWrapper>
    <CustomWrapper>
      <Demo>Nested Custom Wrapper</Demo>
    </CustomWrapper>
  </CustomWrapper>
</View>

问题描述

  • 点击第一个 Button,会触发 CustomWrapper 的 setData,符合预期
  • 点击第二个 Button,会触发 Page 的 setData,不符预期

演示

taro3-nested-custom-wrapper-demo.gif

期望结果

使用 CustomWrapper 后,由 CustomWrapper 实例 setData

实际结果

CustomWrapper 嵌套后,使用了 page.setData

环境信息

Taro CLI 3.3.14 environment info:
    System:
      OS: macOS 12.0.1
      Shell: 5.8 - /bin/zsh
    Binaries:
      Node: 14.8.0 - ~/.nvm/versions/node/v14.8.0/bin/node
      Yarn: 1.22.10 - ~/.nvm/versions/node/v14.8.0/bin/yarn
      npm: 6.14.7 - ~/.nvm/versions/node/v14.8.0/bin/npm
    npmPackages:
      @tarojs/cli: 3.3.14 => 3.3.14 
      @tarojs/components: 3.3.14 => 3.3.14 
      @tarojs/mini-runner: 3.3.14 => 3.3.14 
      @tarojs/react: 3.3.14 => 3.3.14 
      @tarojs/runtime: 3.3.14 => 3.3.14 
      @tarojs/taro: 3.3.14 => 3.3.14 
      @tarojs/webpack-runner: 3.3.14 => 3.3.14 
      babel-preset-taro: 3.3.14 => 3.3.14 
      eslint-config-taro: 3.3.14 => 3.3.14 
      react: 17.0.2 => 17.0.2 

补充信息

通过调试发现 performUpdate 时尝试使用 pageCtx.selectComponent 去查询 CustomWrapper,但飞书小程序以及微信小程序(没有测试其它)的 selectComponent 不支持穿透自定义组件查询,所以查询不到被嵌套的 CustomWrapper

我在我们项目通过重写 TaroRootElement.prototype.performUpdate,一层层地往下查询 CustomWrapper,修复了这个问题,但只在飞书小程序上测试了。相关改动我贴个 pr,麻烦看下这样改是否合理 #10873

@taro-bot2 taro-bot2 bot added F-react Framework - React T-tt Target - 编译到字节跳动小程序 V-3 Version - 3.x labels Dec 9, 2021
@CS-Tao
Copy link
Contributor Author

CS-Tao commented Dec 10, 2021

@Chen-jj 我发现当跳转页面后,如果上一个页面被回收,通过 selectComponent 查不到 CustomWrapper 的 dom 节点,无法使用这个 CustomWrapper 来 setData,应该怎么处理呢?

我尝试了两个 fallback 方案

  1. 将数据交给没有查到的 CustomWrapper 的 Parent CustomWrapper 或 page,执行 setData
  2. 丢弃这份数据

但发现这两个方案都可能导致后续的 setState 异常,比如:

从 page1 跳转到 page2,同时通过 事件通信 去异步通知 page1 内部的某个组件 A(PureComponent) 改变内部状态({ visible: false }),跳转过程中可能 page1 已经被回收,按上面的方案无法正确执行此次状态变更

那么当我从 page2 返回 page1 时,page1 的内容被小程序引擎恢复,此时再去改变组件 A 的内部状态(仍然希望改变为 { visible: false }),此次 setState 并不会触发 render;如果将组件 A 改为继承 Component,会触发 render,但界面不会有任何更新

@CS-Tao
Copy link
Contributor Author

CS-Tao commented Dec 10, 2021

@Chen-jj 我发现当跳转页面后,如果上一个页面被回收,通过 selectComponent 查不到 CustomWrapper 的 dom 节点,无法使用这个 CustomWrapper 来 setData,应该怎么处理呢?

我尝试了两个 fallback 方案

  1. 将数据交给没有查到的 CustomWrapper 的 Parent CustomWrapper 或 page,执行 setData
  2. 丢弃这份数据

但发现这两个方案都可能导致后续的 setState 异常,比如:

从 page1 跳转到 page2,同时通过 事件通信 去异步通知 page1 内部的某个组件 A(PureComponent) 改变内部状态({ visible: false }),跳转过程中可能 page1 已经被回收,按上面的方案无法正确执行此次状态变更

那么当我从 page2 返回 page1 时,page1 的内容被小程序引擎恢复,此时再去改变组件 A 的内部状态(仍然希望改变为 { visible: false }),此次 setState 并不会触发 render;如果将组件 A 改为继承 Component,会触发 render,但界面不会有任何更新

这个问题我在我们项目通过缓存 customWrapper 实例解决了,相关改动提交到 pr 里了

@Chen-jj
Copy link
Contributor

Chen-jj commented Dec 10, 2021

@Chen-jj 我发现当跳转页面后,如果上一个页面被回收,通过 selectComponent 查不到 CustomWrapper 的 dom 节点,无法使用这个 CustomWrapper 来 setData,应该怎么处理呢?

这种情况没能 Get 到,上一个页面被回收了(例如:redirect?)本就不能 setData 吧?有没有具体的测试用例?

@CS-Tao
Copy link
Contributor Author

CS-Tao commented Dec 10, 2021

@Chen-jj 我发现当跳转页面后,如果上一个页面被回收,通过 selectComponent 查不到 CustomWrapper 的 dom 节点,无法使用这个 CustomWrapper 来 setData,应该怎么处理呢?

这种情况没能 Get 到,上一个页面被回收了(例如:redirect?)本就不能 setData 吧?有没有具体的测试用例?

我用的 navagateTo,这个问题在真机上是概率性出现,在飞书开发者工具的远程调试中必现。和飞书小程序引擎的开发者沟通是说当页面位于后台时,出于性能考虑,页面的 webview 可能会被客户端暂时回收。简单描述就是页面的引用还在,但对应的 dom 无法查询到

测试用例可以参考我另一条评论的举例

如果还是不方便复现我可以抽空提供一个 demo 和录屏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-react Framework - React T-tt Target - 编译到字节跳动小程序 V-3 Version - 3.x
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants