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

[alipay]ref不能在componentDidMount后获取实例对象 #4094

Closed
YuanQuan opened this issue Aug 7, 2019 · 7 comments
Closed

[alipay]ref不能在componentDidMount后获取实例对象 #4094

YuanQuan opened this issue Aug 7, 2019 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@YuanQuan
Copy link
Contributor

YuanQuan commented Aug 7, 2019

问题描述
ref不能在componentDidMount后获取实例对象

 ...
newGoldBoxInstance: NewGoldBox;
refNewGoldBox = (node) => this.newGoldBoxInstance = node;
 ...
<NewGoldBox ref={this.refNewGoldBox} onClick={this.boxClick.bind(this)} /> 
...
 componentDidMount(){
        this.newGoldBoxInstance.getNewBoxState()//这里newGoldBoxInstance还未执行绑定
}

期望行为
可以在componentDidMount生命周期后获取ref绑定实例

报错信息

newGoldBoxInstance不存在

系统信息

Taro v1.2 及以上版本已添加 taro info 命令,方便大家查看系统及依赖信息,运行该命令后将结果贴下面即可。

  • 操作系统: [MAC]
  • Taro 版本 [1.13.12]
  • Node.js 版本 [e.g. v9.0.0]
  • 报错平台 [alipay]

补充信息
怀疑是组件生命周期的问题,在子组件生成完成前就对Page组件进行初始化了?

@taro-bot
Copy link

taro-bot bot commented Aug 7, 2019

欢迎提交 Issue~

如果你提交的是 bug 报告,请务必遵循 Issue 模板的规范,尽量用简洁的语言描述你的问题,最好能提供一个稳定简单的复现。🙏🙏🙏

如果你的信息提供过于模糊或不足,或者已经其他 issue 已经存在相关内容,你的 issue 有可能会被关闭。

Good luck and happy coding~

@shenghanqin
Copy link
Collaborator

我估计这个要改的话,ref的绑定逻辑了。
目前是在didMount那里才会执行ref的绑定
taro/packages/taro-alipay/src/create-component.jscomponentTrigger方法里面有设置ref的方法。

if (key === 'componentDidMount') {
    if (component['$$refs'] && component['$$refs'].length > 0) {
      let refs = {}
      component['$$refs'].forEach(ref => {
        let target
        if (ref.type === 'component') {
          const childs = component.$childs || {}
          target = childs[ref.id] || null
        } else {
          const query = my.createSelectorQuery().in(component.$scope)
          target = query.select(`#${ref.id}`)
        }
        commitAttachRef(ref, target, component, refs, true)
        ref.target = target
      })
      component.refs = Object.assign({}, component.refs || {}, refs)
    }
  }

不过我看了微信小程序的源码与支付宝小程序的,两者的设置时机可能不一样。
微信小程序是onReady触发的componentDidMount,而支付宝是更新组件触发的componentDidMount

// 微信小程序
  weappComponentConf.methods['onReady'] = function () {
      this.$component.__mounted = true
      componentTrigger(this.$component, 'componentDidMount')
    }

// 支付宝小程序
  if (!component.__mounted) {
      component.__mounted = true
      componentTrigger(component, 'componentDidMount')
      componentTrigger(component, 'componentDidShow')
    }

@YuanQuan
Copy link
Contributor Author

YuanQuan commented Aug 7, 2019

对这3端的时态都不一样,本来我想自己改的,后来放弃了,感觉必须官方出马了

@shenghanqin
Copy link
Collaborator

对这3端的时态都不一样,本来我想自己改的,后来放弃了,感觉必须官方出马了

我可能会手动加一个setTimeout来延迟执行,或者看didMount之后的生命周期是didShow,那你可以在didShow里面完成单次设置(设置过就不设置了)

@Chen-jj
Copy link
Contributor

Chen-jj commented Aug 8, 2019

@YuanQuan 一开始是可以的,后来感觉是某一支付宝小程序版本改了父子组件间生命周期触发顺序,然后初次获取就有问题了。支付宝先不要用 ref 吧,之后考虑改接支付宝 component2 编译提供的 ref 特性。

@Chen-jj Chen-jj self-assigned this Aug 8, 2019
@shenghanqin
Copy link
Collaborator

确实,小程序的基础库版本升级后,是没法获悉特别准确的升级记录的。
当每次发布正式版的时候,记录一下支付宝版本,支付宝小程序基础库版本,便于之后出现问题后好排查。

@Chen-jj
Copy link
Contributor

Chen-jj commented Jul 3, 2020

Taro 3 应该没有这个问题了。

@Chen-jj Chen-jj closed this as completed Jul 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants