2

In offical react tutorial they first write class component:

class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => this.props.onClick()}>
       {this.props.value}
     </button>
   );
 }
}

and then make it a function component

function Square(props) {
  return (
    <button className="square" onClick={props.onClick}>
      {props.value}
    </button>
  );
}

Why is the onClick change necessary i.e why did we remove the arrow function?

In the first case when we remove the arrow function i.e just keep this.props.onClick() the event happens every time the square renders without even clicking the button and why is it so? ps:I am new to react js , got these doubts when following the tutorial,it would be great if you could give a elaborate answer and any further resources that could help!!thanks in advance.

  • 2
    Without looking at the tutorial more completely, the change doesn't seem to be necessary. Arrow functions are very useful within class components for scoping `this`, but I don't see that as a requirement in this example.. Seems unneccesssary. – Brian Thompson Jun 10 '21 at 14:09
  • yeah but i did not understand why I get alert right away, without clicking the button in first case, and in second case it just works fine as it's a function component not a class component – Vinay Chimmili Jun 10 '21 at 14:10
  • @AGE no you don't need the `() => props.onClick` for the arrow function. – programmerRaj Jun 10 '21 at 14:10
  • because when you put parenthesis in front of a function that mean you called that function thats why in the second case they didn't put parenthesis. in the first case when you click on the button a function will happen (arrow function) and this function will call another function(this.props.onClick) so it is not like the second case – Amir Hossein Jun 10 '21 at 14:16

3 Answers3

5

I'm guessing you did the below?

aka, changed

class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => this.props.onClick()}>
       {this.props.value}
     </button>
   );
 }
}

^ That, to

class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={this.props.onClick()}>
       {this.props.value}
     </button>
   );
 }
}

^ this

If so, you're basically calling this.props.onClick() everytime the component is rendered. The return value of this.props.onClick() would then be set as the onClick value. This is useful for when you want code to be executed that is relative to the onClick event and then return a function that handles the actual onClick event.

To replicate the same as the second example, just do.

class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={this.props.onClick}>
       {this.props.value}
     </button>
   );
 }
}

As the this.props.onClick function is assigned to the onClick prop not called.

Basic Function Calling explanation

function onClickHandler() {
    console.log('I WAS CLICKED!'):
}

function callThis() {

   return onClickHandler;
}

var assignedOnClick = callThis(); < Calls callThis which returns onClickHandler (without calling it)

var alsoAssignedOnClick = onClickHandler;

alsoAssignedOnClick(); < Calls onClickHandler which has just been assigned to the alsoAssignedOnClick variable

Tip: Don't overthink with React or coding in general. Pretty much all of coding is just getting data from A to B, the hard part of it is keeping your data/call stack as minimal as possible.

Jeff Schaller
  • 2,352
  • 5
  • 23
  • 38
LoveDev
  • 257
  • 1
  • 9
  • 1
    The OP didn't use `onClick={this.props.onClick()}` in the question? – evolutionxbox Jun 10 '21 at 14:13
  • 3
    Yes they did "In the first case when we remove the arrow function i.e just keep this.props.onClick()"...aka they called the function (thus assigned the return value which is probably undefined to onClick), not assigned it to onClick – LoveDev Jun 10 '21 at 14:17
1

As @ShubhamKhatri said : "Each time render is called an anonymous function is created and that function when called, calls this.onClick. Hovewer The arrow function does not recreate function everytime." You can read all detail. here

Veysel Turan
  • 203
  • 2
  • 14
1

In the first case, they wrap the callback in charge of handling the click event in an arrow function, to ensure that 'this' is available within the onClick function. This syntax is correct but there is a problem that a different callback is created each time your button is rendered. In most cases this works fine, but if this callback is passed as a prop to other components, these components could be re-rendered and it can bring performance issues. This is a class component's behavior.

The other way to ensure that 'this' is available within the onCLick function is by placing this in your class's constructor:

this.onClick = this.props.onClick.bind(this);

and then just send the function reference as a prop to your components like this:

<button onClick={this.onClick}>
    {props.value}
</button>

In the second case, that they are using functional components, what is being passed as a parameter is the reference to the function. In this case there is no 'this', therefore it makes no sense to wrap the call to your callback function in another arrow function and you cannot use bind. It would be valid to do something like this:

<button className="square" onClick={() => props.onClick()}>
    {props.value}
</button>

but unnecessary since what you would be doing is passing the reference to a function that simply invokes the function in charge of handling the event internally, so it is cleaner to pass the reference to the function directly.

Leader
  • 11
  • 3