【问题标题】:Click handler inside loop (two returns) not working (React JS)单击循环内的处理程序(两个返回)不起作用(React JS)
【发布时间】:2017-08-20 05:50:34
【问题描述】:

我有一个非常简单的 React 片段,它忽略了一个数组并输出选项卡名称。但是我的点击处理程序不再工作(它在我没有循环之前工作)。

这块和我之前的 .map 循环之间的区别在于,这个新块在渲染函数中有两个返回。一个用于 React 所需的外部 div 元素,然后一个用于循环对象。

请问有谁可以成功让点击处理程序再次工作?

请查看我的组件

class TabMenu extends React.Component {
constructor(props) {
    super(props);
    this.state = {

    };
    this.tabMenuList = [
      {
        title: 'My Account',
        section: 'MyAccount'
      },
      {
        title: 'Conference Details',
        section: 'MyAccount'
      },
      {
        title: 'My Abstract',
        section: 'MyAbstract'
      }
    ];
}
handleClick(e){
  e.preventDefault();

  console.log('this is the click handler', this);
  ReactDOM.render(<Conference />,document.getElementById('content'));
}
render() {

  return (
    <div>
      {this.tabMenuList.map(function(menuItem, index){
        return(
          <li data={menuItem.section}>
            <a onClick={this.handleClick.bind(this)} href={'#'}>
              <img src={'assets/img/mail_icon.jpg'} />
              <span>{menuItem.title}</span>
            </a>
          </li>
        )
      })}
    </div>
  );
}
}

【问题讨论】:

  • 您需要在tabMenuList 地图回调上使用粗箭头
  • this 不是您认为的 .map 函数内部的内容,正如上面建议的那样,您需要一个箭头函数。如果你console.log(this),你会看到它引用了Window
  • 您可能还需要将onClick=onClick= 更改为一个onClick=
  • 感谢您的快速回复,尝试了一些箭头功能但还没有工作。请有人介意向我展示箭头功能的外观吗?我还删除了双 onClick。那并不总是存在:)。
  • {this.tabMenuList.map((menuItem, index) =&gt; {

标签: javascript reactjs react-jsx


【解决方案1】:

解决方案

像这样使用 ES6 arrow 函数:

class TabMenu extends React.Component {
constructor(props) {
    super(props);
    this.state = {

    };
    this.tabMenuList = [
      {
        title: 'My Account',
        section: 'MyAccount'
      },
      {
        title: 'Conference Details',
        section: 'MyAccount'
      },
      {
        title: 'My Abstract',
        section: 'MyAbstract'
      }
    ];
}
handleClick(e){
  e.preventDefault();

  console.log('this is the click handler', this);
  ReactDOM.render(<Conference />,document.getElementById('content'));
}
render() {

  return (
    <div>
      {this.tabMenuList.map((menuItem, index) => {
        return(
          <li data={menuItem.section}>
            <a onClick={this.handleClick.bind(this)} href={'#'}>
              <img src={'assets/img/mail_icon.jpg'} />
              <span>{menuItem.title}</span>
            </a>
          </li>
        )
      })}
    </div>
  );
}
}

为什么?

在您的 React 代码中,this 没有引用 TabMenu

在函数中声明 this 时,它会自动默认为全局对象 - 在您的环境中为 Window

由于下面的代码不是在严格模式下,并且由于 this 的值不是由调用设置的,所以 this 将默认为全局对象。

但是,重要的是要知道这一点

然而,在严格模式下, this 的值保持在进入执行上下文时设置的任何值,因此,在以下情况下, this 将默认为 undefined。

为什么?因为根据this 问题和第一个答案,ES6 模块默认为use strict,因此function 中的this 等于undefined

因此,

在箭头函数中,this 是按词法设置的,即它被设置为封闭执行上下文的 this 的值。在全局代码中,它将被设置为全局对象

您的封闭执行上下文是TabMenu

MDN 有一篇关于 this 的精彩文章,以及它如何根据调用 this 的上下文而变化。

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this

【讨论】:

    【解决方案2】:

    试试这个

    <li data={menuItem.section}>
                <a onClick={this.handleClick.bind(this)} href={'#'}>
                  <img src={'assets/img/mail_icon.jpg'} />
                  <span>{menuItem.title}</span>
                </a>
              </li>
    

    而不是

    <li data={menuItem.section}>
                <a onClick=onClick={this.handleClick.bind(this)} href={'#'}>
                  <img src={'assets/img/mail_icon.jpg'} />
                  <span>{menuItem.title}</span>
                </a>
              </li>
    

    或者您可以删除第二次退货可能会起作用

    【讨论】:

    • 感谢您的回复,但我看不出第一个建议有什么不同?
    • 对不起,我忘了编辑答案,现在你可以检查了。你写了两次 onClick
    猜你喜欢
    • 1970-01-01
    • 2018-02-08
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多