Reputation: 24112
I have:
...
setActive(section) {
this.setState({
currentSection: section
});
console.log('Current view is'+this.state.currentSection);
}
render() {
return <div>
<div className="section">
<HeaderButton active text="test1" count={23} backgoundColor={'#c04c36'} onClick={() => this.setActive.bind('test1')}/>
</div>
<div className="section">
<HeaderButton text="test2" count={45} backgoundColor={'#ffe698'} onClick={() => this.setActive.bind('test2')}/>
</div>
<div className="section">
<HeaderButton text="test3" count={4} backgoundColor={'#198a75'} onClick={() => this.setActive.bind('test3')}/>
</div>
</div>
}
But when I click on those component nothing at all happens. What am I doing wrong?
Upvotes: 2
Views: 61
Reputation: 74
The problem is that you are both using the arrow function, and binding as well. You are also not binding to an execution context.
This is a confusing concept.
When you call an onClick without an arrow function, you need to bind it.
Thus, a call like this...
onClick = {this.setActive.bind(this)}
Needs to be called or else this.setActive will lose its binding. It is bound to the execution context that you would like it to run in, in this case that being this
An ES6 arrow function is lexically bound and does not need to be bound to an execution context.
thus, you can have...
onclick ={() => this.setActive()}
Which will automatically run in the context where it is written, thus not needing the binding.
Also, you are binding to a string instead of an execution context (usually a component).
Take out the bind and your function should run.
Upvotes: 1
Reputation: 30360
Avoid calling .bind()
in the onclick
handler itself. Instead, you can call setActive()
directly via the this
variable seeing that the context of the arrow function is that of your component:
render() {
return <div>
<div className="section">
<HeaderButton active text="test1" count={23}
backgoundColor={'#c04c36'}
onClick={() => this.setActive('test1')}/>
</div>
<div className="section">
<HeaderButton text="test2" count={45}
backgoundColor={'#ffe698'}
onClick={() => this.setActive('test2')}/>
</div>
<div className="section">
<HeaderButton text="test3" count={4}
backgoundColor={'#198a75'}
onClick={() => this.setActive('test3')}/>
</div>
</div>
}
Alternatively, to optimize your render()
method, you could create pre-bound function instances to avoid use of arrow functions in your render method:
constructor(props) {
super(props);
/* Bind setActive to this component/class instance */
this.setActiveTest1 = this.setActive.bind(this, 'test1')
this.setActiveTest2 = this.setActive.bind(this, 'test2')
this.setActiveTest3 = this.setActive.bind(this, 'test3')
}
setActive(section) {
this.setState({
currentSection: section
});
console.log('Current view is'+this.state.currentSection);
}
render() {
return <div>
<div className="section">
<HeaderButton active text="test1" count={23}
backgoundColor={'#c04c36'}
onClick={this.setActiveTest1 }/>
</div>
<div className="section">
<HeaderButton text="test2" count={45}
backgoundColor={'#ffe698'}
onClick={this.setActiveTest2}/>
</div>
<div className="section">
<HeaderButton text="test3" count={4}
backgoundColor={'#198a75'}
onClick={this.setActiveTest3}/>
</div>
</div>
}
Upvotes: 0
Reputation: 1089
You should bind your events in constructor but not in attribute itself.
Upvotes: 0