Reaccionar: "esto" no está definido dentro de una función componente
class PlayerControls extends React.Component {
constructor(props) {
super(props)
this.state = {
loopActive: false,
shuffleActive: false,
}
}
render() {
var shuffleClassName = this.state.toggleActive ? "player-control-icon active" : "player-control-icon"
return (
<div className="player-controls">
<FontAwesome
className="player-control-icon"
name='refresh'
onClick={this.onToggleLoop}
spin={this.state.loopActive}
/>
<FontAwesome
className={shuffleClassName}
name='random'
onClick={this.onToggleShuffle}
/>
</div>
);
}
onToggleLoop(event) {
// "this is undefined??" <--- here
this.setState({loopActive: !this.state.loopActive})
this.props.onToggleLoop()
}
Quiero actualizar loopActive
el estado al alternar, pero this
el objeto no está definido en el controlador. Según el documento del tutorial, this
debería consultar el componente. ¿Me estoy perdiendo de algo?
ES6 React.Component
no vincula automáticamente los métodos consigo mismo. Debes unirlos tú mismo constructor
. Como esto:
constructor (props){
super(props);
this.state = {
loopActive: false,
shuffleActive: false,
};
this.onToggleLoop = this.onToggleLoop.bind(this);
}
Hay un par de maneras.
Una es agregar
this.onToggleLoop = this.onToggleLoop.bind(this);
el constructor.
Otra son las funciones de flecha
onToggleLoop = (event) => {...}
.
Y luego está onClick={this.onToggleLoop.bind(this)}
.
Escribe tu función de esta manera:
onToggleLoop = (event) => {
this.setState({loopActive: !this.state.loopActive})
this.props.onToggleLoop()
}
Funciones de flecha gruesa
el enlace para la palabra clave this es el mismo fuera y dentro de la función de flecha gruesa. Esto es diferente a las funciones declaradas con función, que pueden vincularlo a otro objeto al invocarlo. Mantener este enlace es muy conveniente para operaciones como mapeo: this.items.map(x => this.doSomethingWith(x)).
Me encontré con un enlace similar en una función de renderizado y terminé pasando el contexto this
de la siguiente manera:
{someList.map(function(listItem) {
// your code
}, this)}
También he usado:
{someList.map((listItem, index) =>
<div onClick={this.someFunction.bind(this, listItem)} />
)}