Taro: 给 map 渲染的组件加上 key 时,列表打乱刷新几次后出现匿名函数作用域传值紊乱

Created on 7 Jun 2019  ·  9Comments  ·  Source: NervJS/taro

问题描述
使用 {array.map(...)} 渲染组件列表。为提高渲染效率,给 map 渲染的组件加上 key。但发现加上后,出现在匿名函数中由上级作用域传进的值非预期的问题。

复现步骤

  1. 复现代码如下:
import Taro, { Component, Config } from "@tarojs/taro";
import { View, Text, Button } from "@tarojs/components";
import "./index.less";

export interface IndexState {
  items: string[];
}

const samples: string[] = ["name", "pity","simple", "back off","total","point","now"];

export default class Index extends Component<{}, IndexState> {
  config: Config = {
    navigationBarTitleText: "首页"
  };

  state: IndexState = {
    items: []
  };

  render() {
    return (
      <View className="index">
        <Text>Hello world!</Text>
        <Button onClick={this.onButtonClick}>Generate random items</Button>
        {this.state.items.map(item => {
          return (
            <Text
              key={item}
              onClick={() => {
                console.log(item);
              }}
            >
              {item}
            </Text>
          );
        })}
      </View>
    );
  }

  private onButtonClick = () => {
    let items: string[] = shuffle(samples);

    this.setState({
      items
    });
  };
}

// 打乱数组
function shuffle<T>(arr: T[]): T[] {
  for (var i = 1; i < arr.length; i++) {
    var _random = Math.floor(Math.random() * (i + 1));
    var _ref = [arr[_random], arr[i]];
    arr[i] = _ref[0];
    arr[_random] = _ref[1];
  }
  return arr;
}
  1. 运行小程序后,多次点击 "Generate random items"
  2. 点击打乱的列表中的各项,会发现 console.log(item) 在控制台输出的字符串与该项在屏幕上渲染的字符串不一致!
  3. 删除列表组件的 key 属性,行为恢复正常

期望行为
行为与 React 一致,作用域值传递正常,不因为加上 key 而导致行为异常。

报错信息
(无报错)

系统信息
Taro CLI 1.3.0-beta.6 environment info:
System:
OS: Windows 10
Binaries:
Node: 10.13.0 - D:\Dev\Env\NodeJs\node.EXE
Yarn: 1.16.0 - ~\AppData\Roaming\npm\yarn.CMD
npm: 6.4.1 - D:\Dev\Env\NodeJs\npm.CMD

补充信息
不确定原因,大致猜测与转译后语义差异有关。

Most helpful comment

为什么点击事件里箭头函数改为 bind 传值不会紊乱

All 9 comments

欢迎提交 Issue~

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

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

Good luck and happy coding~

@dizys 哪个端

@dizys 这种写法刚好会触发到微信小程序端的 bug。

你的 key 可以用 index,或者数组内容改为对象,以对象的 id 做 key,而不是直接以 item 为 key。

已在微信开发者社区提了一个 bug

为什么点击事件里箭头函数改为 bind 传值不会紊乱

@lerhxx 框架对循环内的箭头函数做了处理,如果想深究的话看看编译后的 js 应该就明白了。

非常感谢!~等待微信官方回应`

@dizys @lerhxx 官方回应:

image

看来短期是不会被修复了,先绕过吧。

微信开发者社区对应帖子

为什么点击事件里箭头函数改为 bind 传值不会紊乱

果然可以!!谢谢

为什么点击事件里箭头函数改为 bind 传值不会紊乱

果然可以!!谢谢

我这还是混乱的

Was this page helpful?
0 / 5 - 0 ratings