reactjs - props - react native jsx
ReactJS: el controlador onClick no se activa cuando se coloca en un componente secundario (2)
Recientemente comencé a trabajar con ReactJS
. Específicamente, estoy utilizando react-rails
ruby gem y react-bootstrap
components.
Tengo una pregunta sobre la colocación de escuchas de eventos onClick
en componentes secundarios.
Como puede ver en el siguiente ejemplo de código, tengo un componente principal que ''llama'' a un componente secundario en su función de render
. Dentro de esa función de render
, tengo un oyente React onClick
que llama a handleToggle
cuando se 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>`
Desafortunadamente, esto no funciona de la manera que pensé que sería. ToggleIconButton::handleToggle
nunca recibe llamadas. En cambio, el oyente onClick
se coloca en IconButton
y hace referencia a ToggleIconButton::handleToggle
.
No quiero agregar ningún comportamiento adicional a IconButton
. De la forma en que lo veo, no se debe colocar una lógica condicional en IconButton
. Todo lo que debe hacer es representar un ícono y un botón y no tener que preocuparse por ningún evento del navegador. Para eso es ToggleIconButton
.
Aunque sé que podría envolver una React Div
alrededor de IconButton
y escribir un oyente onClick
allí (lo he intentado y funciona), parece que es un poco tonto.
¿Alguien sabe una buena manera de hacer esto? ¡Gracias chicos!
No necesita crear un componente secundario si antes de llamar al nodo crea una var para hacer referencia al renderizado, es decir,
var self = this;
Entonces, por ejemplo (esto es ideado y la var self no es necesaria en este caso, pero en el caso de declaraciones de retorno anidadas sería necesario).
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.
}
});
Mejor aún, podrías vincular esto a la función.
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.
}
});
O para seguir la sugerencia de captray en los comentarios
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.
}
});
Por lo tanto, la forma correcta de manejar eventos en este caso sería pasar el controlador de eventos al componente secundario. Hay algunas maneras de lograr lo que desea, y podría implementar este comportamiento de manera diferente (no estoy seguro de cuál es el caso de uso), pero conecté un ejemplo en JSX para usted que demuestra el manejo de eventos típicos entre los componentes principales y secundarios. Lo puedes encontrar aquí...
Solo piénsalo de esta manera:
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!" />
)
}
});