0

I try to learn React but seems in the new version there are some changes:

class Reactapp extends React.Component{ constructor(){ super(); } sayMassage(){ console.log(this.props.children); } render(){ var sayMassage = this.sayMassage.bind(this); return( <div> <h3> Hello {this.props.word}</h3> <p> <a href="#" onClick={this.sayMassage}> Click Me </a> </p>; </div> ); } } ReactDOM.render( <div> <Reactapp word="React">This is a ReactJS 15.5 Tutorial</Reactapp> </div>, document.getElementById('root') ); 

This code should work but seems I am missing something. It should console.log "This is a ReactJS 15.5 Tutorial" super is called before this so this could not be null.

I tried to bind this but I don't know how, My code seems to fail. The old code with createReactClass had auto-binding tho.

0

5 Answers 5

2

Its a scope issue, just write this line in the constructor, it will work:

this.sayMassage = this.sayMassage.bind(this); 

And remove this one:

var sayMassage = this.sayMassage.bind(this); 

Check the working example:

class Reactapp extends React.Component{ constructor(){ super(); this.sayMassage = this.sayMassage.bind(this); } sayMassage(){ console.log(this.props.children); } render(){ return( <div> <h3> Hello {this.props.word}</h3> <p> <a href="#" onClick={this.sayMassage}> Click Me </a> </p> </div> ); } } ReactDOM.render( <Reactapp word="React">This is a ReactJS 15.5 Tutorial</Reactapp>, document.getElementById('root') );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id='root'/>

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

1 Comment

Thanks for help. I understand the idea now.
0

You can do what Mayank said, but there is another way - using arrow functions. That way, the function will automatically take 'this' of the class instance.

It will be something like the below. You will have to remove the binding that you did originally, of course.

class Reactapp extends React.Component{ sayMassage = () => { console.log(this.props.children); } render(){ return( <div> <h3> Hello {this.props.word}</h3> <p><a href="#" onClick={this.sayMassage}>Click Me</a></p>; </div> ); } } ReactDOM.render( <div> <Reactapp word="React">This is a ReactJS 15.5 Tutorial</Reactapp> </div>, document.getElementById('root') ); 

P.S. There is a typo in the function name, sayMassage (should be sayMessage), unless you actually wanted to say Massage :-)

1 Comment

Thanks mate. it worked, and i misstyped It is indeed Message :) not Massage
0

One option to solve your scoping problem is to move the binding to the class constructor like so:

constructor(props) { super(props); this.state = {...}; this.sayThaiMassage = this.sayThaiMassage.bind(this); 

}

or using a fat arrow function like so:

myFatGreekMassage = (event ) => { ...your code } 

While fat arrows functions keeping the scope (this is that) your problem is also solved.

Comments

0

First, remove your line var sayMassage = this.sayMassage.bind(this);

It has to be in the constructor, like this :

constructor(){ super(); this.sayMassage = this.sayMassage.bind(this); } 

Or, to keep the context when calling your function and not having to bind, you can use an arrow function in the link, like this :

<a href="#" onClick={() => this.sayMassage}>Click Me</a> 

Comments

0

Try onClick={() => ::this.sayMassage}

And remove var sayMassage = this.sayMassage.bind(this);

--

:: here make the bind this with the current scope.

() => the arrow function declare a function which will be executed when you click on the element. If you don't declare the call as a function it will be executed every time you reload the page, without action needed.

Comments