onClick не работает React js

Я пытаюсь вызвать функцию, когда пользователь нажимает на div (используя onClick в реакции). Мне не нужно передавать какие-либо аргументы в этот момент, просто нужно вызвать функцию. Я новичок в реакции. Я так извиняюсь за свое невежество. Благодарю.

var Test = React.createClass({

btnTapped: function(){
    console.log('tapped!');
},
render: function() {
    var stationComponents = this.props.stations.map(function(station, index) {

    return <div onClick={btnTapped()}><img src="img/test.png" />{station}</div>;

    });
    return <div>{stationComponents}</div>;
   }
});

var cards = ["amazon", "aeo", "aerie", "barnes", "bloomingdales", "bbw","bestbuy", "regal", "cvs", "ebay", "gyft", "itunes", "jcp", "panera", "staples", "walmart", "target", "sephora", "walgreens", "starbucks"];

ReactDOM.render(<Test stations={cards} />, document.getElementById('test-div'));

Ответ 1

Если ваша система сборки поддерживает babel, используйте функцию ES6 arrow в вашем коде реакции.

Если вы используете класс ES6 для создания компонентов, используйте привязку метода на уровне конструктора, чтобы избежать привязки при каждом вызове рендеринга, а также предоставить ключ к тегу div внутри функции карты.

class Test extends React.Component {
    constructor(props) {
        super(props);
        this.btnTapped = this
            .btnTapped
            .bind(this);
    }
    btnTapped() {
        console.log('tapped');
    }
    render() {

        return (
            <div>
                {this
                    .props
                    .stations
                    .map((station, index) => {
                        return <div key={index} onClick={this.btnTapped}>{station}</div>
                    })
                }
            </div>
        )
    }
}

var cards = ["amazon", "aeo", "aerie", "barnes", "bloomingdales", "bbw", "bestbuy", "regal", "cvs", "ebay", "gyft", "itunes", "jcp", "panera", "staples", "walmart", "target", "sephora", "walgreens", "starbucks"];

    
ReactDOM.render(
    <Test stations={cards}/>, document.getElementById('test-div'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<body>
  <div id="test-div"></div>
</body>

Ответ 2

Вы должны установить функцию в атрибут onClick, а не вызывать ее. Должно быть: onClick={this.btnTapped} вместо onClick={btnTapped()}.

Также это можно сделать так:

<div 
  onClick={function(e) {
    this.btnTapped(); //can pass arguments this.btnTapped(foo, bar);          
  }}
 >

Обычно используется, когда вам нужно передать аргумент вашей функции.

Также, чтобы иметь возможность получить контекст компонента из внешней функции, вы должны использовать метод bind(this). Нравится: onClick={btnTapped.bind(this)}

И так как вы используете функцию области действия для отображения массива, новый контекст создается внутри: this.props.stations.map(function(station, index){}. И this переопределяется. Просто используйте вместо этого функцию стрелки:

var stationComponents = this.props.stations.map((station, index) => {

   return <div onClick={this.btnTapped}><img src="img/test.png" />{station}</div>;

});

Ответ 3

Вы пропустили this ключевое слово перед функцией. Также вы должны предоставить функцию, но не называть ее

<div onClick={this.btnTapped}>

ОБНОВИТЬ:

Вы пропустили то, что вы переопределите this в функции обратного вызова карты.

Использовать функцию стрелки

this.props.stations.map((station, index) => {
  return <div onClick={this.btnTapped}><img src="img/test.png" />{station}</div>;
});

или привязать контекст к функциям

this.props.stations.map(function (station, index) {
  return <div onClick={this.btnTapped}><img src="img/test.png" />{station}</div>;
}.bind(this));

Ответ 4

Всякий раз, когда вы хотите использовать функцию в методе рендеринга, сначала вам нужно связать эти методы в конструкторе. Еще одна вещь, когда вы не хотите передавать какие-либо аргументы в методы, которые вам нужно вызывать, используйте этот onClick = {this.btnTapped} вместо onClick = {this.btnTapped()}. Спасибо.

import React, {Component} from 'react';
import ReactDOM from 'react-dom';

export default class Test extends Component {
constructor (props) {
    super(props);
//set cards value in state then you don't need to use props...
    this.state = {
        cards: ["amazon", "aeo", "aerie", "barnes", "bloomingdales", 
        "bbw","bestbuy", "regal", "cvs", "ebay", "gyft", "itunes", 
        "jcp", "panera", "staples", "walmart", "target", "sephora", 
        "walgreens", "starbucks"]
    }
    this.btnTapped = this.btnTapped.bind(this);
    // bind all the methods which you're using the "this.state" inside it....
}

btnTapped (card) {
    console.log("Coming here:::" + card)
}

render() {
    var cards = this.state.cards
    return (
        <div>
            {/* if you don't want to pass an arguments use this... */}
            {
                cards.map((card, i) => 
                    <button key = {i} onClick = {this.btnTapped}>{card}</button>
                )
            }
            {/* if you want to pass arguments use this  */}
            {
                cards.map((card, i) =>
                    <button key = {i} onClick = {(e) => this.btnTapped(card)}>{card}</button>
                )
            }
        </div>
    );
}
}
ReactDOM.render(<Test />, document.getElementById('test-div'));