The .bind() method creates a new function, so the right hand side is also a function. Thus, that line redefines this.toggleMood as another function created by the .bind() method. The reason for doing this is explained in the exercise description:
Due to the way that event handlers are bound in JavaScript, this.toggleMood() loses its this when it is used on line 20. Therefore, the expressions this.state.mood and this.setState on lines 7 and 8 won’t mean what they’re supposed to… unless you have already bound the correct this to this.toggleMood .
That is why we must bind this.toggleMood to this on line 8.
For an in-depth explanation of this kind of binding trickery, begin with the React docs. For the less curious, just know that in React, whenever you define an event handler that uses this , you need to add this.methodName = this.methodName.bind(this) to your constructor function.
(I think “lines 7 and 8” in this text is a mistake for “lines 12 and 13”. I reported it as a bug the other day, but it has not been fixed for now.) More detailed explanations will be found in the React docs linked in this text and the document about the .bind() method.
const changeColor = this.state.color == green ? yellow : green;
and
this.changeColor = this.changeColor.bind(this); put this in constructor
This will work
An alternative solution for using this in your method:
you can convert your method to an arrow function, with that you will not have to use bind.
ex:
class Example extends React.Component {
constructor(props) {
super(props);
this.state = { weather: 'sunny' };
}
makeSomeFog = () => {
// will work without bind because we are using an arrow function
this.setState({
weather: 'foggy'
});
}
}
you haven’t used “setState” in your render method, you are using “setState” on an event handler which will only execute when you click the button.
but you can’t use “setState” directly in your render methods, why?
changing your state is causing your component to re-render so imagine you are using setState directly in your render method, it’s an infinite loop!! changing the state will make a re-render and render will cause a setState which will change the state and causing a re-render again and again.
Hello!!
I’d have a question regarding this exercise…
Why does this.changeColor = this.changeColor.bind(this);
must be placed under the constructor method, and not under the changeColor method?
I use this opportunity to tip my hat to the creators of this react course. Really well made, and much funnier than the other classes that I took in codacademy
The code in that line redefines this.changeColor as another function. If you know what this is doing, you’ll probably know why this line is in the constructor. I’ve posted earlier about what this kind of line is doing, so I hope you find it helpful.
I’m not sure to understand why <div style={{background: this.state.color}}> should be written with two curly braces, is someone could please explain it to me?
In JSX, JavaScript expressions are written inside curly braces, and since JavaScript objects also use curly braces, the styling is written inside two sets of curly braces {{}}
This is first example in the linked React documentation of avoiding having to manually bind the handler function.
The code does not work in CodePen. The handleClick method does not get called when clicking on the button.
Can someone see what is wrong? This was copied and pasted directly from the React document. I only added the
two lines.
//html
<div id="root"></div>
//css
body {
padding: 5px
}
//code
class LoggingButton extends React.Component {
// This syntax ensures `this` is bound within handleClick. me: (this is a React doc comment)
handleClick = () => {
console.log('this is:', this);
};
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<LoggingButton />);
I just realised that we are learning class components and not functional components. I think it would have been better if you could make a note about it. Otherwise, I think its a bit confusing to differentiate between two.