-1

I am looking at this code: https://reactjs.org/docs/state-and-lifecycle.html

I do not understand why I need to use () => this.tick() instead of just this.tick(). The prior calls a function that uses this.tick(), yet when I change () => this.tick() to this.tick(), the code stops working. this.tick() is no longer being called even though it itself is a function. () => this.tick() seems to be just an unnecessary step and yet it is necessary.

I think I am misunderstanding functions as objects.

Thank you

GG.
  • 21,083
  • 14
  • 84
  • 130
FranktheTank
  • 292
  • 3
  • 9
  • If you change it to not be an arrow function, you need to: 1. **not** call it; and 2. make sure it has the right context (so `this` is what you expect it to be). – jonrsharpe Nov 28 '18 at 19:44
  • 2
    Please show all relevant code. We don't know what context you are using this in or looking at on a very long documentation page. See [mcve] – charlietfl Nov 28 '18 at 19:46
  • 1
    There are two completely different things. `this.tick()` is a function *call*, while `() => this.tick()` is a function *definition*. Maybe the following makes it clearer, copy this into your terminal: `alert('you see me'); function foo() { alert("you don't see me"); }`. – Felix Kling Nov 28 '18 at 19:51
  • [relevant](https://stackoverflow.com/q/3800512/497418). – zzzzBov Nov 28 '18 at 19:51

5 Answers5

3
GG.
  • 21,083
  • 14
  • 84
  • 130
0

() => this.tick() is a function that when executed will call this.tick() with the appropriate context. If you didn't want to use arrow syntax, you would need to bind the this context similar to this.tick.bind(this);

Tyler Jennings
  • 8,761
  • 2
  • 44
  • 39
0

The arrow function used there is needed to bind the this context, so that it can use this in it's own function.

If you would have only setTimeout( this.tick, 1000 ), it would rightfully call the function on the class, however, that function wouldn't have a this scope...

...unless you bind the this scope in the constructor, or as part of the setTimeout call itself

To do it in the constructor you would have something like

class Clock extends Component {
  constructor() {
    super();
    this.tick = this.tick.bind(this);
  }
  // other functions
  tick() {
    this.setState(/*.. state content ..*/):
  }
}

another option would be the

setTimeout( this.tick.bind( this ), 1000 );

but that would do the same as what the arrow function is doing for you anyhow, so why not use the arrow function instead.

Another option would be the experimental class properties where you would still have an arrow function, but as this is not the most optimal solution when it comes to testing, I will not directly discuss that one

Icepickle
  • 12,689
  • 3
  • 34
  • 48
0

Firstly, setInterval takes a function as a parameter. Hence unless this.tick returns a function, passing this.tick() to setInterval is incorrect.

setInterval defers the callback method in the event loop. And hence at the time of its execution, the current reference to this will have been lost, as its scope is within its parent function which would have completed its execution. So this would be pointing to window or undefined ins strict mode.

To make it work, you need to preserve the reference, for which we create a closure by creating a new function () => this.tick. Now the reference will be preserved even after parent funtion completes its execution.

Easwar
  • 5,132
  • 1
  • 11
  • 21
0

You need to give the function a callback to be invoked. A callback is a function that is to be executed after another function has finished. For example using a setTimeout is a built-in function, you give tick a callback because once setTimeout is finished you would like tick to be invoked.

Hope this helps!

Jacob Bralish
  • 261
  • 3
  • 13