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'));