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

子组件的标签有id属性时,父组件的回调函数异常 #7317

Closed
ilzhi opened this issue Aug 12, 2020 · 5 comments
Closed

子组件的标签有id属性时,父组件的回调函数异常 #7317

ilzhi opened this issue Aug 12, 2020 · 5 comments
Labels
F-react Framework - React good first issue Good for newcomers T-weapp Target - 编译到微信小程序 V-3 Version - 3.x
Milestone

Comments

@ilzhi
Copy link

ilzhi commented Aug 12, 2020

相关平台

微信小程序

复现仓库

https://github.com/li-z/taro-bug
小程序基础库: 2.12.0
使用框架: React

复现步骤

运行项目后点击跳转到详情页,然后返回首页。然后触发子组件的 onClick 事件时,回调函数却还是详情页的函数。去掉id属性后正常。

期望结果

有无id属性都应正常

实际结果

有id属性异常

环境信息

Taro CLI 3.0.7 environment info:
    System:
      OS: macOS 10.14.1
      Shell: 3.2.57 - /bin/bash
    Binaries:
      Node: 10.16.2 - ~/.nvm/versions/node/v10.16.2/bin/node
      Yarn: 1.17.3 - ~/.nvm/versions/node/v10.16.2/bin/yarn
      npm: 6.9.0 - ~/.nvm/versions/node/v10.16.2/bin/npm
    npmPackages:
      @tarojs/components: 3.0.7 => 3.0.7 
      @tarojs/mini-runner: 3.0.7 => 3.0.7 
      @tarojs/react: 3.0.7 => 3.0.7 
      @tarojs/runtime: 3.0.7 => 3.0.7 
      @tarojs/taro: 3.0.7 => 3.0.7 
      @tarojs/webpack-runner: 3.0.7 => 3.0.7 
      babel-preset-taro: 3.0.7 => 3.0.7 
      eslint-config-taro: 3.0.7 => 3.0.7 
      react: ^16.10.0 => 16.13.1 
    npmGlobalPackages:
      typescript: 3.5.3
@taro-bot2 taro-bot2 bot added F-react Framework - React T-weapp Target - 编译到微信小程序 V-3 Version - 3.x labels Aug 12, 2020
@xinggangling
Copy link

xinggangling commented Aug 14, 2020

你的子组件ID一样的话,会有这个问题,taro自己会生成一个UID,一个UID对应一个hash里面的一个事件

@ilzhi
Copy link
Author

ilzhi commented Aug 14, 2020

你的子组件ID一样的话,会有这个问题,taro自己会生成一个UID,一个UID对应一个hash里面的一个事件

ID不一样

@Chen-jj Chen-jj added this to the 3.0.10 milestone Sep 3, 2020
@Chen-jj Chen-jj modified the milestones: 3.0.10, 3.0.11 Sep 10, 2020
@ZakaryCode ZakaryCode modified the milestones: 3.0.11, 3.0.12 Sep 18, 2020
@Chen-jj Chen-jj modified the milestones: 3.0.15, 3.0.16 Oct 23, 2020
@mishengqiang
Copy link

mishengqiang commented Nov 3, 2020

你的子组件ID一样的话,会有这个问题,taro自己会生成一个UID,一个UID对应一个hash里面的一个事件

ID不一样

哈哈哈哈😂,和我的问题一样,搞得我都开始怀疑react了。
我遇到了同样的问题,但是我发现在小程序中会出现这种现象,但是编译成h5没这个问题,经过一步步调试,发现是因为id的问题。taro编译成微信小程序(我只开发了微信小程序,其它平台小程序代码没看)时,会给每一个组件生成一个唯一id,然后使用id来派发事件(并不是将事件绑定到元素上),这个有点像:document.getElementById(id).onclick=function(){},因此如果你的id相同(在整个程序中)后面的事件函数就会把前面的事件函数覆盖掉。

你说你的Child.tsx中的ID的不同,只看Child.tsx文件两个View的ID确实是不同的,但是你可能忘记了你将Child.tsx分别在index.tsx和detail.tsx中使用了且Child.tsx中的ID是写死的,这样就会导致index.tsx和detail.tsx中的<View id='a1' onClick={onClick}>a1</View>具有相同的ID都是a1,当打开detail.tsx页面时,a1的点击事件函数就会被替换掉,a2同样如此。

解决方案就是保证每次调用组件生成的id是不同的,需要动态生成id不能写死。我的解决方案是使用固定前缀+时间戳。如果你不需要这个id你可以不写,这样taro就会自动生成一个唯一的id

下面是调试时看到Taro位于src/dom/event.ts的源代码:

export function eventHandler (event: MpEvent) {
  if (event.currentTarget == null) {
    event.currentTarget = event.target
  }

  const node = document.getElementById(event.currentTarget.id)
  if (node != null) {
    node.dispatchEvent(createEvent(event, node))
  }
}

我认为Taro应该在官方文档中注明必须保持id是全局唯一的。

@Chen-jj Chen-jj added the good first issue Good for newcomers label Nov 5, 2020
@Chen-jj
Copy link
Contributor

Chen-jj commented Nov 5, 2020

不太好改,所有页面都挂在同一颗 DOM 树下,共用一个 eventSource,暂时先保证组件全局 id 唯一吧。

我们先在文档加个提示。

@Chen-jj
Copy link
Contributor

Chen-jj commented Dec 17, 2021

Taro v3.4 修复

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-react Framework - React good first issue Good for newcomers T-weapp Target - 编译到微信小程序 V-3 Version - 3.x
Projects
None yet
Development

No branches or pull requests

5 participants