处理动态生成按钮的点击次数

时间:2016-12-15 23:25:53

标签: javascript reactjs javascript-events ecmascript-6

背景

您好,我对C#和VB.net非常满意,但我是Javascript的新手,目前也在尝试学习React。我正在开发一个简单的购票应用程序用于学习目的。我能够在一天内在Angular中创建这个应用程序,但React已被证明更加困难。很明显我需要用React学习JS基础知识,而我觉得我不需要任何先前的知识来学习Angular。

问题

我创建了一个Create React App项目并开始修补它(我通过修补来学习最好)。我现在能够为每个参展商(剧院连锁店)生成一个按钮。这些按钮是动态生成的,因为最终,我不知道有多少参展商。经过大量的谷歌搜索和Stack Overflowing,这是我提出的代码(请原谅任何noob语法/格式化):

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class TicketOrder extends Component {
  constructor () {
    super();

    this.handleClick = this.handleClick.bind(this);

    // List of Exhibitors
    this.exhibList = {
      TestA     : "abc",
      TestB     : "bcd",
      TestC     : "cde"
    };
  }

  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Ticketz</h2>
          <p id="userGuide">Hello. Please select an Exhibitor:<br/><br/> </p>
        </div>
        <br/>
        <div>
        {
          Object.keys(this.exhibList).map(function(key) {
            return (<p><button className="button" onClick={key => this.handleClick}>{key}</button></p>);
          })
        }
        </div>
    </div>
    );
  }

  handleClick () {
    console.log("Clicked!");
  };
}

export default TicketOrder;

我认为我犯了一些基本的错误,我承认我还没有完全掌握React的概念,所以请放轻松我吧!无论我尝试什么,我得到的错误是“Uncaught TypeError:无法读取属性'handleClick'of undefined”。我已经尝试了上述代码的许多变体而没有运气。有人会非常友好地告诉我我的代码/概念有什么问题吗?

一旦这个问题得到解决,我仍然有一个潜在的问题,我无法概念化哪个有句柄知道哪个按钮被按下了。例如,如果用户按下TestA,则控制台.log(“abc”)。最后,一旦我对JS和React有了更多的了解,我猜我会根据按下的按钮改变handleClick中组件的状态。任何有关如何实现这一目标的见解都将非常受欢迎。

提前致谢! 查理

4 个答案:

答案 0 :(得分:2)

&#34; this&#34;您尝试访问的权限无法访问,因为您处于功能范围内。要避免它,您可以使用箭头函数语法。 此外,map函数正在迭代您的键数组,因此您只需要将handleClick函数作为参数提供。 你的映射是这样的:

 {
    Object.keys(this.exhibList).map((item, index) => {
       return (<p><button key={index} className="button" onClick={() => this.handleClick(item)}>{item}</button></p>);
    })
 }

在箭头函数{}中,&#34;这个&#34;将是您要访问的人(也称为TicketOrder)。还要记住给你映射的任何元素赋一个唯一的键属性(我把索引放在前面的例子中),这有助于React算法知道哪些元素发生了变化。 Cf here

你的handleClick看起来像这样:

handleClick = (message) => {
  console.log("Clicked!", message);
};

您可以看到一个不同的键作为参数传递,并根据用户点击的按钮显示。

这就是整个事情对我的影响:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class TicketOrder extends Component {
  // Drop the constructor you don't need it anymore, especially with Create React App
  exhibList = {
    TestA       : "abc",
    TestB       : "bcd",
    TestC       : "cde",
  }

  handleClick = (key) => {
    console.log("Clicked!", key);
  };

  render() {
    return (
      <div className="App">
          <div className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <h2>Ticketz</h2>
              <p id="userGuide">Hello. Please select an Exhibitor:<br/><br/> </p>
          </div>
          <br/>
          <div>
          {
              Object.keys(this.exhibList).map((item, index) => {
                  return (<p><button key={index} className="button" onClick={() => this.handleClick(item)}>{item}</button></p>);
              })
          }
          </div>
     </div>
    );
  }
}

export default TicketOrder;

答案 1 :(得分:0)

将您的onClick更改为:

onClick={this.handleClick.bind(this, key)}

和您的handleClick

 handleClick(ctx) {
   console.log(ctx, "Clicked!");
 }

答案 2 :(得分:0)

更改您的代码:

onClick={() => this.handleClick(key)}

handleClick(key) {
  console.log('Clicked!', key)
}

如果你想要这个活动:

onClick={event => this.handleClick(event, key)}

handleClick(event, key) {
  console.log('Clicked!', event, key)
}

希望有所帮助! :)

答案 3 :(得分:0)

你的map函数不知道里面有这个,因此无法读取未定义“的属性'handleClick'。这意味着你正试图调用undefined.handleClick,在这种情况下,this未定义。

您可以使用胖箭头函数() => {}this绑定到开箱即用的函数。为此,请将地图功能更改为

map((key, index) => {
  return (
     <p key={index}>
     <button
       className="button" 
       onClick={() => this.handleClick(key)}>{key}
     </button>
     </p>);
})

还要注意index参数,迭代器中的每个子节点都应该有唯一的键。

然后你的把手点击:

handleClick(key){
   console.log('Clicked',key)
}