2

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?

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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>
}

5 Comments

The second method gives me Uncaught TypeError: Cannot read property 'setActive' of undefined
@imperium2335 opps - small typo, just updated answer. Does that help?
Thanks it's no longer erroring but it isn't doing anything at all.
Ok I had to put onClick={this.props.onClick} in my HeaderButton component, seems to work now.
@imperium2335 nice! Glad I could help :-)
0

You should bind your events in constructor but not in attribute itself.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.