I've done some changes in code of React JS book, but

Hello. Sorry for my English, I’ve just learning it.
I’m reading the book about React JS. Thanks a lot to Kirupa for it!
In the section 10 (about React events) there is an example of counter with button “+”: If I click on the button, the number in div is increase by 1, and if the Shift key is pressed the number increase by 10. I’m trying to add addition functionality: button “-” with same behavior but with decrease. But this code doesn’t working. If I press in “+” or “-” the number increase by 1, then by 10, and then buttons doesn’t work any more. What the main problem with my code? Can anybody help to me? Thanks a lot!

     class CounterParent extends React.Component {
               constructor(props) {
                    super(props);
                    this.state = {
                        count: 0
                    };
...               
               changeCount(newCount){
                    this.setState({
                        count: newCount
                    });                    
                }
                increase(e) {                                        
                    this.changeCount(this.state.count + e.shiftKey?10:1);
                }
                decrease(e) {
                    this.changeCount(this.state.count - e.shiftKey?10:1);
                }
...
                   return (
                        <div style={backgroundStyle}>
                            <Counter display={this.state.count} />
                            <button onClick={this.increase} style={buttonStyle}>+</button>
                            <button onClick={this.decrease} style={buttonStyle}>-</button>
                        </div>
                    );

Hi Alex,

You’re missing a key component to making your event handlers work: this binding. When you pass a normal function or method into an event handler, the value of this gets lost. And you need it to be your component instance so this.changeCount() will work. To do this you can force bind the component this into those event handlers. As seen on https://www.kirupa.com/react/events_in_react.htm you can do this in the constructor using the bind() method. For you, with both event handlers, that would look something like:

           constructor(props) {
                super(props);
                this.state = {
                    count: 0
                };

                this.increase = this.increase.bind(this);
                this.decrease = this.decrease.bind(this);
                // ...

Now your events should work.

By the way this is just one approach to solving this issue. You may also see arrow functions being used to do something similar.

Hi! Thank you for your help! I actually have this code with bind methods in my constructor. I just hadn’t show it in example of my code. I have a problem in another place. My program is passed tests with console.log in events, but the number with counter is refresh once by clicking the buttons, and then click is only refresh console tests. This problem is related to how React updates the DOM elements, but I don’t know how to do it right

That might be from your use of the ternary conditional then. You’re using

this.state.count + e.shiftKey?10:1

which is seen as

(this.state.count + e.shiftKey)?10:1

When what you want is

this.state.count + (e.shiftKey?10:1)

Try adding those parens and see if that helps

Thank you. You are right! But the main problem was in another. I had understand that I needed to use this.setState with function:

changeCount(newCount) {
       this.setState((prevState)=> ({
             count: prevState.count + newCount
        }));
}

Now my code is working well.