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()
}
I want to update loopActive
state on toggle, but this
object is undefined in the handler. According to the tutorial doc, I this
should refer to the component. Am I missing something?
Write your function this way:
http://www.react.express/fat_arrow_functions
I ran into a similar bind in a render function and ended up passing the context of
this
in the following way:I've also used:
There are a couple of ways.
One is to add
this.onToggleLoop = this.onToggleLoop.bind(this);
in the constructor.Another is arrow functions
onToggleLoop = (event) => {...}
.And then there is
onClick={this.onToggleLoop.bind(this)}
.If you call your created method in the lifecycle methods like componentDidMount... then you can only use the
this.onToggleLoop = this.onToogleLoop.bind(this)
and the fat arrow functiononToggleLoop = (event) => {...}
.The normal approach of the declaration of a function in the constructor wont work because the lifecycle methods are called earlier.
ES6 React.Component doesn't auto bind methods to itself. You need to bind them yourself in constructor. Like this: