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

map 循环调用 render 方法渲染的组件不能在事件方法中获取正常遍历参数 #5946

Closed
Aliveing opened this issue Apr 10, 2020 · 7 comments
Assignees

Comments

@Aliveing
Copy link

Aliveing commented Apr 10, 2020

问题描述

描述:当 map 遍历渲染组件时,被渲染的组件不能在类似于 onClick 事件中获取正常的遍历参数,遍历值始终是最后一个遍历的数据

我提了两个类似的问题 #5473#5138,都是类似的问题,但是至今都没有任何有用回复就关闭了

#5473#5138 这种原生组件(Switch, Picker)才会发生的问题,现在普通 View 也会了!

顺便提一下,真的挺怀疑 taro-bot 的 issue 管理中所谓的:如果您在这 15 天中更新更多信息自动关闭的流程会自动取消 是不是真的有效。

复现步骤

  1. 新建一个页面文件,复制示例代码到页面文件(我用的 微信小程序开发工具,不知道是否有关)
  2. 跳转到这个页面文件,界面分为上下两种,上面绿色背景为好用的map写法,下面红色背景为issue中提到的有问题的map写法
  3. 在有问题的map写法中依次点击1,2,3,100000,200000,300000,会看到:点击 1 的时候显示点击了 100000,点击 2 的时候显示 200000, 点击 3 的时候会显示 300000
  4. 正常的是一一对应的,即绿色背景的 toast 显示
import Taro, { Component } from '@tarojs/taro';
import { View } from '@tarojs/components';

class BugExample extends Component {

    _itemStyle = 'margin: 10px; text-align:center;';

    grandItemStyle = (index) => {
        const colors = ['#eee8aa', '#87ceeb'];
        return `background-color:${colors[index]}; padding: 10px; margin: 10px; border-radius: 20px;`
    }

    itemStyle = 'margin-bottom: 10px';
    
    renderItems = (arr_item, index) => {
        return arr_item.map(item => {
            return <View
                style={this.grandItemStyle(index)}
                key={`arr_item_${item}`}
                onClick={() => {
                    Taro.showToast({ title: `我点了${item}` }); 
                }}
            >{item}</View>
        })
    }

    _panelStyle = 'color: black; text-align: center; padding: 10px;';
    _headerStyle = 'font-size: 32px; font-weight: bold;';

    render() {
        const arr1 = Array.from({ length: 3 }).map((item, index) => index + 1);
        const arr2 = Array.from({ length: 3 }).map((item, index) => (index + 1) * 100000);
        const arr = [arr1, arr2];
        return <View>
            {/* 没问题的写法 */}
            <View style={`${this._panelStyle} background-color: #9acd32`}>
                <View style={this._headerStyle}> 好用的Map写法 </View>
                {
                    arr.map((arr_item, index) => {
                        return <View key={`view_${index}`} style={this.itemStyle}>
                            {
                                arr_item.map(item => {
                                    return <View
                                        style={this.grandItemStyle(index)}
                                        key={`arr_item_${item}`}
                                        onClick={() => {
                                            Taro.showToast({ title: `我点了${item}` });
                                        }}
                                    >{item}</View>
                                })
                            }
                        </View>
                    })
                }
            </View>
            {/* 有问题的写法 */}
            <View style={`${this._panelStyle} background-color: #d73a49;`}>
                <View style={this._headerStyle}> 有问题的Map写法 </View>
                {
                    arr.map((arr_item, index) => {
                        return <View key={`view_${index}`} style={this.itemStyle}>
                            {this.renderItems(arr_item, index)}
                        </View>
                    })
                }
            </View>
        </View>
    }
}
export default BugExample;

期望行为

事件函数可以正常获取遍历参数

报错信息

没有报错信息,我还是像 #5473 一样贴一张运行gif
https://gfycat.com/snivelingdecimalemperorshrimp

系统信息

👽 Taro v2.1.4

Taro CLI 2.1.4 environment info:
System:
OS: macOS 10.15.4
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 10.16.3 - ~/.nvm/versions/node/v10.16.3/bin/node
Yarn: 1.22.0 - ~/.yarn/bin/yarn
npm: 6.14.4 - ~/.nvm/versions/node/v10.16.3/bin/npm
npmPackages:
@tarojs/components: 2.1.4 => 2.1.4
@tarojs/mini-runner: 2.1.4 => 2.1.4
@tarojs/plugin-babel: 2.1.4 => 2.1.4
@tarojs/plugin-csso: 2.1.4 => 2.1.4
@tarojs/plugin-sass: 2.1.4 => 2.1.4
@tarojs/plugin-uglifyjs: 2.1.4 => 2.1.4
@tarojs/router: 2.1.4 => 2.1.4
@tarojs/taro: 2.1.4 => 2.1.4
@tarojs/taro-alipay: 2.1.4 => 2.1.4
@tarojs/taro-h5: 2.1.4 => 2.1.4
@tarojs/taro-qq: 2.1.4 => 2.1.4
@tarojs/taro-quickapp: 2.1.4 => 2.1.4
@tarojs/taro-swan: 2.1.4 => 2.1.4
@tarojs/taro-tt: 2.1.4 => 2.1.4
@tarojs/taro-weapp: 2.1.4 => 2.1.4
@tarojs/webpack-runner: 2.1.4 => 2.1.4
eslint-config-taro: 2.1.4 => 2.1.4
eslint-plugin-taro: 2.1.4 => 2.1.4
nerv-devtools: ^1.5.6 => 1.5.6
nervjs: ^1.5.6 => 1.5.6
stylelint-config-taro-rn: 2.1.4 => 2.1.4
stylelint-taro-rn: 2.1.4 => 2.1.4
taro-ui: ^2.3.3 => 2.3.3

补充信息

  • 2020-04-13 22:37:27 taro@2.1.4 仍有此问题

我想介绍一下Github 的 <details></details> 标签,这个标签可以把冗长的信息折叠起来,就像 #5473 中我折叠了系统信息,这样就不会导致整个issue中系统信息占了大量篇幅,像这样点击下面的 详细信息 就可以看到:

👽 Taro v2.1.4

Taro CLI 2.1.4 environment info:
System:
OS: macOS 10.15.4
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 10.16.3 - ~/.nvm/versions/node/v10.16.3/bin/node
Yarn: 1.22.0 - ~/.yarn/bin/yarn
npm: 6.14.4 - ~/.nvm/versions/node/v10.16.3/bin/npm
npmPackages:
@tarojs/components: 2.1.4 => 2.1.4
@tarojs/mini-runner: 2.1.4 => 2.1.4
@tarojs/plugin-babel: 2.1.4 => 2.1.4
@tarojs/plugin-csso: 2.1.4 => 2.1.4
@tarojs/plugin-sass: 2.1.4 => 2.1.4
@tarojs/plugin-uglifyjs: 2.1.4 => 2.1.4
@tarojs/router: 2.1.4 => 2.1.4
@tarojs/taro: 2.1.4 => 2.1.4
@tarojs/taro-alipay: 2.1.4 => 2.1.4
@tarojs/taro-h5: 2.1.4 => 2.1.4
@tarojs/taro-qq: 2.1.4 => 2.1.4
@tarojs/taro-quickapp: 2.1.4 => 2.1.4
@tarojs/taro-swan: 2.1.4 => 2.1.4
@tarojs/taro-tt: 2.1.4 => 2.1.4
@tarojs/taro-weapp: 2.1.4 => 2.1.4
@tarojs/webpack-runner: 2.1.4 => 2.1.4
eslint-config-taro: 2.1.4 => 2.1.4
eslint-plugin-taro: 2.1.4 => 2.1.4
nerv-devtools: ^1.5.6 => 1.5.6
nervjs: ^1.5.6 => 1.5.6
stylelint-config-taro-rn: 2.1.4 => 2.1.4
stylelint-taro-rn: 2.1.4 => 2.1.4
taro-ui: ^2.3.3 => 2.3.3

如果您有功能上的建议,可以提到 FeatHub

使用上的问题,欢迎在「Taro 社区」一起交流

@taro-bot
Copy link

taro-bot bot commented Apr 10, 2020

CC @luckyadam

@taro-bot
Copy link

taro-bot bot commented Apr 10, 2020

欢迎提交 Issue~

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

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

Good luck and happy coding~

@Aliveing Aliveing changed the title map 循环调用 render 方法渲染的组件不能在的事件方法中获取正常遍历参数 map 循环调用 render 方法渲染的组件不能在事件方法中获取正常遍历参数 Apr 12, 2020
@cloudZQY
Copy link
Contributor

cloudZQY commented Apr 15, 2020

这个bug可以通过生成的代码看出来。

function _createItemsData(_$uid) {
      var _this2 = this;

      return function (arr_item, index) {
        var loopArray2 = arr_item.map(function (item, __index0) {
          item = {
            $original: (0, _taroWeapp.internal_get_original)(item)
          };
          var $loopState__temp2 = (0, _taroWeapp.internal_inline_style)(_this2.grandItemStyle(index));
          var $loopState__temp4 = "arr_item_" + item.$original;

          var _$indexKey = "czzzz" + __index0;

          _this2.anonymousFunc0Map[_$indexKey] = function () {
            _taroWeapp2.default.showToast({ title: "\u6211\u70B9\u4E86" + item.$original });
          };

          return {
            $loopState__temp2: $loopState__temp2,
            $loopState__temp4: $loopState__temp4,
            _$indexKey: _$indexKey,
            $original: item.$original
          };
        });
        return {
          loopArray2: loopArray2,
          arr_item: arr_item
        };
      };
    }

由于arr1和arr2共用了一个_createItemsData,而代码var _$indexKey = "czzzz" + __index0; 这一行的"czzzz" 是由

// taro-transformer-wx/src/class.ts  line 263
t.binaryExpression('+', t.stringLiteral(createRandomLetters(5)), index)

生成的随机字符串。
实际上他们的_$uid是可以识别arr1和arr2的,所以当"czzzz" 换乘 _$uid 时可以解决这个问题。

源码改动是
t.binaryExpression('+', t.stringLiteral(createRandomLetters(5)), index) 改成
t.binaryExpression('+', t.identifier(CLASS_COMPONENT_UID), index),bug就解决了。
经测试,这个bug是解决了,但是不知道这个随机字符串有没有深意,会不会导致其他的问题,需要评估一下。

提了一个pr
#6001

@luckyadam

@fokq
Copy link

fokq commented Apr 20, 2020

1.42 版本的hook编写的页面也有这个问题。render 函数渲染的组件不能在事件方法中获取正常遍历参数,在render函数中再用map,map中调用函数的参数会一样。

@wudi98
Copy link

wudi98 commented Apr 26, 2020

https://wudi98.blog.csdn.net/article/details/105778616
我也遇到了这个问题。可以参考下我的解决办法。如果解决了麻烦给个关注,点个赞,谢谢~

@Chen-jj
Copy link
Contributor

Chen-jj commented Jul 2, 2020

Taro3 应该没有这个问题了。

@Chen-jj Chen-jj closed this as completed Jul 2, 2020
@wudi98
Copy link

wudi98 commented Jul 2, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants