ReactJS映射函数找不到未定义的属性

Posted

技术标签:

【中文标题】ReactJS映射函数找不到未定义的属性【英文标题】:ReactJS map function cannot find property of undefined 【发布时间】: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?

【问题讨论】:

OnClick Event binding in React.js的可能重复 【参考方案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>
  );

【讨论】:

以上是关于ReactJS映射函数找不到未定义的属性的主要内容,如果未能解决你的问题,请参考以下文章

找不到 mcrypt => 调用未定义的函数 Laravel\mcrypt_create_iv()

Angular 7:“找不到具有未指定名称属性的控件”

休眠映射 - 在类中找不到属性名称的设置器

找不到标识符,该怎么解决

超链接 `<a>` 未调用映射的 Servlet。返回 404:找不到资源 [重复]

Angular-Cli 'ng g c my-new-component' 错误:找不到(未定义)和找不到(未定义)