Cómo configurar un controlador de eventos en Reaccionar sub-componente
-
21-12-2019 - |
Pregunta
Estoy teniendo problemas para conseguir los elementos de menú conectado a un controlador de eventos.Aquí está una maqueta de la interfaz de usuario que muestra los cambios de estado a lo largo del tiempo.Es un menú desplegable (a través de Bootstrap), con la raíz del elemento de menú que muestra la selección actual:
[ANN]<click ... [ANN] ... [BOB]<click ... [BOB]
[Ann] [Ann]
[Bob]<click + ajax [Bob]
[Cal] [Cal]
El objetivo final es cambiar el contenido de la página de forma asincrónica basada en la selección del usuario.Haciendo click sobre Bob debe desencadenar la handleClick
, pero no lo es.
Como una nota del lado, no estoy terriblemente contento con la forma en componentDidMount llamadas this.handleClick();
, pero por ahora funciona como una forma de obtener inicial del menú de contenido desde el servidor.
/** @jsx React.DOM */
var CurrentSelection = React.createClass({
componentDidMount: function() {
this.handleClick();
},
handleClick: function(event) {
alert('clicked');
// Ajax details ommitted since we never get here via onClick
},
getInitialState: function() {
return {title: "Loading items...", items: []};
},
render: function() {
var itemNodes = this.state.items.map(function (item) {
return <li key={item}><a href='#' onClick={this.handleClick}>{item}</a></li>;
});
return <ul className='nav'>
<li className='dropdown'>
<a href='#' className='dropdown-toggle' data-toggle='dropdown'>{this.state.title}</a>
<ul className='dropdown-menu'>{itemNodes}</ul>
</li>
</ul>;
}
});
$(document).ready(function() {
React.renderComponent(
CurrentSelection(),
document.getElementById('item-selection')
);
});
Estoy casi segura de que mi nublada comprensión de javascript alcance tiene la culpa, pero todo lo que he probado hasta ahora ha fallado (incluyendo tratando de pasar el controlador de abajo a través de los apoyos).
Solución
El problema es que va a crear el elemento de nodos mediante una función anónima, y dentro de ese this
significa que el window
.La solución es agregar .bind(this)
a la función anónima.
var itemNodes = this.state.items.map(function (item) {
return <li key={item}><a href='#' onClick={this.handleClick}>{item}</a></li>;
}.bind(this));
O crear una copia de this
y utilizar en su lugar:
var _this = this, itemNodes = this.state.items.map(function (item) {
return <li key={item}><a href='#' onClick={_this.handleClick}>{item}</a></li>;
})
Otros consejos
Como puedo entender la especificación de la tarea de "Anna", "Bob", "Cal, la solución puede ser la siguiente (basado en un reaccionan componente y ES6):
Básico de demostración en vivo está aquí
import React, { Component } from "react"
export default class CurrentSelection extends Component {
constructor() {
super()
this.state = {
index: 0
}
this.list = ["Anna", "Bob", "Cal"]
}
listLi = list => {
return list.map((item, index) => (
<li key={index}>
<a
name={item}
href="#"
onClick={e => this.onEvent(e, index)}
>
{item}
</a>
</li>
))
}
onEvent = (e, index) => {
console.info("CurrentSelection->onEvent()", { [e.target.name]: index })
this.setState({ index })
}
getCurrentSelection = () => {
const { index } = this.state
return this.list[index]
}
render() {
return (
<div>
<ul>{this.listLi(this.list)}</ul>
<div>{this.getCurrentSelection()}</div>
</div>
)
}
}