ReactJS: обработчик onClick не срабатывает при размещении на дочернем компоненте
Недавно я начал работать с ReactJS
. В частности, я использую компоненты react-rails
ruby gem и react-bootstrap
.
У меня вопрос о размещении onClick
прослушивателей событий в дочерних компонентах.
Как видно из примера кода ниже, у меня есть родительский компонент, который "вызывает" дочерний компонент в своей функции render
. Внутри этой функции render
у меня есть React onClick
listener, который вызывает handleToggle
при нажатии.
###* @jsx React.DOM ###
ToggleIconButton = React.createClass
getInitialState: ->
toggleOn: false
handleToggle: (evt) ->
this.setState(toggleOn: !this.state.toggleOn)
render: ->
`<IconButton onClick={this.handleToggle}>Toggle Button</IconButton>`
IconButton = React.createClass
render: ->
# BsButton and BsGlyphicon are React-Bootstrap components
`<BsButton>
<BsGlyphicon glyph={this.props.glyph} />
{" " + this.props.text}
</BsButton>`
К сожалению, это не работает так, как я думал. ToggleIconButton::handleToggle
никогда не вызывается. Вместо этого слушатель onClick
размещается на IconButton
и ссылается на ToggleIconButton::handleToggle
.
![React Dev Tool Screen]()
Я не хочу добавлять никаких дополнительных действий в IconButton
. Как я вижу это, условная логика не должна быть помещена в IconButton
. Все, что он должен делать, это значок и кнопка, и не нужно беспокоиться о каких-либо событиях в браузере. Это для ToggleIconButton
.
Хотя я знаю, что могу обернуть React Div
вокруг IconButton
и написать там прослушиватель onClick
(я пробовал это, и он работает), похоже, что это немного болтливо.
Кто-нибудь знает хороший способ сделать это? Спасибо, ребята!
Ответы
Ответ 1
Таким образом, надлежащим способом обработки событий в этом случае было бы передать обработчик события дочернему компоненту. Есть несколько способов выполнить то, что вы хотите, и я мог бы реализовать это поведение по-разному (не уверен, что такое вариант использования), но я подключил пример JSX для вас, который демонстрирует типичную обработку событий между родительскими и дочерними компонентами. Вы можете найти его здесь...
JS Fiddle
Просто подумайте об этом так:
var ParentComponent = React.createClass({
render: function(){
return (
<ChildComponent onSomeEvent={this.handleThatEvent} />;
)
},
handleThatEvent: function(e){
//update state, etc.
}
});
var ChildComponent = React.createClass({
render: function(){
return (
<input type="button" onClick={this.props.onSomeEvent} value="Click Me!" />
)
}
});
Ответ 2
Вам не нужно создавать дочерний компонент, если перед вызовом node вы создаете var для ссылки на рендеринг, это i.e.
var self = this;
Итак, например (это надуманно, и var self не требуется в этом случае, но в случае вложенных операторов return потребуется).
var ParentComponent = React.createClass({
render: function(){
var self = this;
return (
<input type="button" onClick={self.handleThatEvent} value="Click Me!" />;
)
},
handleThatEvent: function(e){
//update state, etc.
}
});
Еще лучше, вы можете привязать это к функции.
var ParentComponent = React.createClass({
render: function(){
return (
this.state.array.map(function(){
return (<input type="button" onClick={this.handleThatEvent} value="Click Me!" />);
}.bind(this));
)
},
handleThatEvent: function(e){
//update state, etc.
}
});
Или следить за предложением предложения в комментариях
var ParentComponent = React.createClass({
render: function(){
return (
this.state.array.map(function(){
return (<input type="button" onClick={this.handleThatEvent} value="Click Me!" />);
}, this);
)
},
handleThatEvent: function(e){
//update state, etc.
}
});