-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Taro 3.0.0-rc.0 中 componentDidMount 中通过 Taro.createSelectorQuery.select 无法获取指定元素 #6501
Comments
正常情况下, 你可以监听页面的 onReady 事件,在元素渲染后再查询。
但是,@yuche rc2 版本 并没有执行。
Taro.eventCenter.once(Taro.Current.router.onReady, () => {
const query = Taro.createSelectorQuery()
query.select(this.viewId).boundingClientRect()
query.exec(res => {
console.log(res, 'res')
})
console.log('onReady')
}) |
@Chen-jj rc2 版本 Taro.eventCenter.once(Taro.Current.router.onReady, () => {}) 不会执行,请抽空看一下。 |
componentDidMount 代表 React 组件组装完毕交给 Taro 处理, Taro 刷新到 UI 是有延迟的, 就像 createSelectorQuery 一样的延迟. 所以 componentDidMount 时节点还不存在. 解决办法有3种:
如果 1 和 2 都不适合, 可以试试 3, 但要考虑去重和防抖. |
@cncolder 刚刚使用 3 试了一下,ref 只能拿到组件,并不意味着页面组件dom 已经渲染完成。 |
@cncolder 试了一下 ,还是不行 receiveRef = node => {
if (!node) return;
this.viewRef = node
const query = Taro.createSelectorQuery()
query.select('#' + this.viewId).boundingClientRect()
query.exec(res => {
console.log('未延迟', res)
})
setTimeout(() => {
const query = Taro.createSelectorQuery()
query.select('#' + this.viewId).boundingClientRect()
query.exec(res => {
console.log('延时500毫秒', res)
})
console.log('onReady')
}, 500);
} 未延迟 [null] |
@yuche 我是在3 4层深的子组件中,只能使用 eventCenter 来使用 onReady ,参考的 #6221 发现个很奇怪的问题 Taro.eventCenter.once(Taro.Current.router?.onReady, () => {
console.log('[ok]')
}) 但是如果加了判断,就不会执行ok,更离奇的是 除了 onLayout 别的props字段都没事,onLayout 是 function 类型 if (this.props.onLayout) {
Taro.eventCenter.once(Taro.Current.router?.onReady, () => {
console.log('[ok]')
})
} |
@cncolder 真的不行,您看看 我试了 beta6 rc0 rc2 都不行 <View
ref={node => node && Taro.createSelectorQuery()
.select(`#${node.id}`)
.boundingClientRect()
.exec(console.log)
}
onClick={onClick}
className={className} style={style} {...other}
>
{children}
</View> |
看起来你的方法能解决我的问题 |
@charmtiger 你的 View 没有 id, onLayout 是你的业务代码, 解决问题之前要排除业务代码的干扰. |
@yuche 我已经暂时得出结论,当组件是根据接口参数,来判断是否实例化,也就是说当页面 onReady 的时候,这个组件并没有存在于组件树中,等接口返回后,再实例化组件,在组件的 componentDidMount 中直接调用 query 和使用 eventCenter 都无法查找到元素和执行。另外我对 cncolder 的 ref 的方式,在上述的情况中,同样无法通过多次执行 ref 来拿到元素,只会执行一次。 我认为目前 eventCenter 的方式,只是利用小程序页面的 onReady,对于后来出现的dom是不适用的。理想情况是每次渲染过后,都会有一次类似 Vue.nextTick 的回调,不过感觉不容易实现。 我知道这里不是论坛,我也在大量的尝试各种可能,尽可能确认问题,如果啰嗦了很抱歉🤗。 --------- 更新 刚刚发现 Taro 提供了 Taro.nextTick,使用后问题解决,另外请问 Taro.nextTick 能否代替 eventCenter 的方式? |
Taro 2.1.5, 本地调试正常可以通过createSelectorQuery准确获取到指定内置组件的高度,并成功渲染;但真机调试获取到的组件高度就不准确了。any suggestions? @charmtiger |
@SamChangi 我看 taroui 也是用 延时 来 query的,我也是改用 如果查不到元素,就延时 反复查。 |
fixed, thanks a lot |
这个先打开,后续我们再找有没有更好的方案 |
之前taro2版本组件内是要加 const query = Taro.createSelectorQuery().in(this.$scope) 改为 const query = Taro.createSelectorQuery() (实测环境):"@tarojs/taro": "3.0.0-rc.3", 试试? |
`//查询dom的宽度和高度,注意这里获得的是一个px单位 //不断查询直到有结果 |
在 #6776 之后,nextTick 函数一定会在 onReady 之后运行 |
close #6501 Co-authored-by: vdfor <[email protected]> Co-authored-by: disflyer <[email protected]>
问题描述
Taro 3.0.0-rc.0 中 自定义的 component 在 componentDidMount 中通过 Taro.createSelectorQuery.select 无法获取指定元素
复现步骤
期望行为
componentDidMount 中可获取到元素
报错信息
无
系统信息
Taro v3.0.0-rc.0
Taro CLI 3.0.0-rc.0 environment info:
System:
OS: macOS 10.15.5
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 12.16.3 - /usr/local/bin/node
Yarn: 1.16.0 - /usr/local/bin/yarn
npm: 6.14.4 - /usr/local/bin/npm
npmPackages:
@tarojs/components: 3.0.0-rc.0 => 3.0.0-rc.0
@tarojs/taro: 3.0.0-rc.0 => 3.0.0-rc.0
@tarojs/webpack-runner: 3.0.0-rc.0 => 3.0.0-rc.0
eslint-config-taro: 3.0.0-rc.0 => 3.0.0-rc.0
nervjs: ^1.5.6 => 1.5.6
react: ^16.10.0 => 16.13.1
taro-ui: 3.0.0-alpha.1 => 3.0.0-alpha.
The text was updated successfully, but these errors were encountered: