taro 在切到后台的tabbar页面调用getCurrentInstance会获得当前前台页面实例

yhuiod9q  于 22天前  发布在  其他
关注(0)|答案(1)|浏览(19)

相关平台

微信小程序

复现仓库

https://github.com/xty1992a/taro-nav-current-instance.git
小程序基础库: 抖音/微信都存在此问题
使用框架: React

复现步骤

简介

本仓库用来复现Taro.getCurrentInstance在tabbar页面中,
某些场景下无法获得真正页面实例的问题。

详述

  1. 应用存在一个全局性的状态,页面会订阅这个状态做一些刷新的动作,将导致子组件重渲染。
  2. 某些子组件需要拿到自己所属的页面实例做一些事情。(某些dom api、广播一些页内事件给兄弟组件 etc.)
  3. 设页面[A、B]是tabbar页面时,当A被激活,然后切到B,A此时处于后台,它的组件不会被卸载。如果此时在B页面刷新全局状态,导致A页面调用了getCurrentInstance,将获取到B的页面实例。

复现步骤

  1. 编译进入小程序后,访问首页后,切换到我的
  2. 点击获取地理位置按钮
  3. 可以来回切换点击按钮

期望结果

返回方法调用页面的实例

实际结果

总是返回当前路由栈顶的路由实例

环境信息

👽 Taro v3.6.5

  Taro CLI 3.6.5 environment info:
    System:
      OS: macOS 13.5.2
      Shell: 5.9 - /bin/zsh
    Binaries:
      Node: 16.20.0 - ~/.nvm/versions/node/v16.20.0/bin/node
      Yarn: 1.22.19 - ~/.nvm/versions/node/v16.20.0/bin/yarn
      npm: 8.19.4 - ~/.nvm/versions/node/v16.20.0/bin/npm
    npmPackages:
      @tarojs/cli: 3.6.5 => 3.6.5 
      @tarojs/components: 3.6.5 => 3.6.5 
      @tarojs/helper: 3.6.5 => 3.6.5 
      @tarojs/plugin-framework-react: 3.6.5 => 3.6.5 
      @tarojs/plugin-platform-alipay: 3.6.5 => 3.6.5 
      @tarojs/plugin-platform-h5: 3.6.5 => 3.6.5 
      @tarojs/plugin-platform-jd: 3.6.5 => 3.6.5 
      @tarojs/plugin-platform-qq: 3.6.5 => 3.6.5 
      @tarojs/plugin-platform-swan: 3.6.5 => 3.6.5 
      @tarojs/plugin-platform-tt: 3.6.5 => 3.6.5 
      @tarojs/plugin-platform-weapp: 3.6.5 => 3.6.5 
      @tarojs/react: 3.6.5 => 3.6.5 
      @tarojs/runtime: 3.6.5 => 3.6.5 
      @tarojs/shared: 3.6.5 => 3.6.5 
      @tarojs/taro: 3.6.5 => 3.6.5 
      @tarojs/taro-loader: 3.6.5 => 3.6.5 
      @tarojs/webpack5-runner: 3.6.5 => 3.6.5 
      babel-preset-taro: 3.6.5 => 3.6.5 
      eslint-config-taro: 3.6.5 => 3.6.5 
      react: ^18.0.0 => 18.2.0

补充信息

taro3取消了useScope,建议以getCurrenInstance替代,在上述场景中,产生了gap,希望能修复。

我能想到的方式是编译时为每一个自定义组件的props中透传一个pid,这个id的顶层由所在页面根节点onShow时获取并缓存的一个页面实例提供,通过组件树的方式提供。
然后组件内通过类似 useBelongInstance(props) 的方式,从路由栈中返回命中的页面实例。这样就确保了组件只能拿到自己所属页面的实例。

h6my8fg2

h6my8fg21#

似乎想复杂了,用useContext应该就可以,还是taro2那个奇怪的useContext留下的印象太深刻了😂

思路还是页面onShow时缓存实例,向下提供实例即可。

相关问题