【问题标题】:ReactJS map function cannot find property of undefinedReactJS映射函数找不到未定义的属性
【发布时间】:2017-03-31 02:36:05
【问题描述】:

我还在学习 ReactJS。我正在挑战自己编写一个非常基本的待办事项应用程序(就像一个人一样),但我在调用 onClick 函数时遇到了问题。

var List = React.createClass({

  handleClick: function () {
    alert("Clicked!");
  },

  render: function () {

    var list = this.props.items;
    var items = list.map(function(item){
      return (
        <li style={{borderBottom:'1px solid red'}}>
          <label onClick={this.handleClick}>
            <input type="checkbox" />
            {item}
          </label>
        </li>
      );
    });

    return (
      <ul>{items}</ul>
    )
  }
});

这里的问题是 onClick={this.handleClick} 不能被调用,因为它不在渲染函数的返回调用中。

我需要做什么才能从地图函数内部访问 handleClick?

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

map 函数的第二个参数是一个值,用于定义 执行回调时this 的范围。

.map( callback( currentValue, index, array), value_for_this/scope_to_run_in )

所以你可以修改你的map函数如下:

var items = list.map(function(item){
  return (
    <li style={{borderBottom:'1px solid red'}}>
      <label onClick={this.handleClick}>
        <input type="checkbox" />
        {item}
      </label>
    </li>
  );
}, this);

您还可以使用箭头函数,其中this 是 隐式绑定:

var items = list.map((item) => {
  return (
    <li style={{borderBottom:'1px solid red'}}>
      <label onClick={this.handleClick}>
        <input type="checkbox" />
        {item}
      </label>
    </li>
  );
});

【讨论】:

  • 这解决了问题,但现在点击也在页面加载时触发(因此在页面加载时连续获得 3 个警报,每个列表项一个)
  • 奇怪。通过使用括号 ( onClick = {this.handleclick()} ) 在 onClick 上设置它时,您没有调用 handleClick ,是吗?
【解决方案2】:

您遇到的问题是您对list.map 的调用将使用与render 方法中不同的this 调用传递的函数。

一个简单的解决方法是在外部作用域中获取this 并将其存储在一个变量中,然后在您的内联函数中使用该变量。

render: function () {
    var self = this;
 // ^^^^^^^^^^^^^^^^

    var list = this.props.items;
    var items = list.map(function(item){
      return (
        <li style={{borderBottom:'1px solid red'}}>
          <label onClick={self.handleClick}>
                       // ^^^^
            <input type="checkbox" />
            {item}
          </label>
        </li>
      );
    });

    return (
      <ul>{items}</ul>
    )
}

【讨论】:

  • 这是一个不错的技巧。感觉有点太容易了——这有什么缺点吗?
  • @MattSaunders 这是 ES2015 之前的代码中非常常见的模式。它本质上与 ES2015 箭头函数的作用相同,您只是手动完成。还有其他选项(重新绑定、将this 传递给map 等),但这种方式的性能相似且至少具有可读性。
【解决方案3】:

您应该将 this 显式绑定到 handleClick 函数以引用 React 组件而不是 map 函数,因此您可以按如下方式重构代码:

var items = list.map(renderListItem.bind(this));

并在你的 React 类中添加 renderListItem 方法如下:

renderListItem(item) {
  return (
    <li style={{borderBottom:'1px solid red'}}>
      <label onClick={this.handleClick}>
        <input type="checkbox" />
        {item}
      </label>
    </li>
  );
}

【讨论】:

    猜你喜欢
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多