单击循环内的处理程序(两个 returns)不起作用(React JS)

Click handler inside loop (two returns) not working (React JS)

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

这块和我之前有 .map 循环的区别在于,这块新块在渲染函数中有两个 returns。一个用于 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>
  );
}
}

试试这个

<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>

或者您可以删除第二个 return 可能会有用

解决方案

像这样使用 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 在您的环境中。

Since the following code is not in strict mode, and because the value of this is not set by the call, this will default to the global object.

但是,重要的是要知道

In strict mode, however, the value of this remains at whatever it was set to when entering the execution context, so, in the following case, this will default to undefined.

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

因此,

In arrow functions, this is set lexically, i.e. it's set to the value of the enclosing execution context's this. In global code, it will be set to the global object

您的封闭执行上下文是 TabMenu

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

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