Author avatar

Gaurav Singhal

How to Use setInterval Callback with Context in React

Gaurav Singhal

  • Apr 25, 2020
  • 6 Min read
  • 18,052 Views
  • Apr 25, 2020
  • 6 Min read
  • 18,052 Views
Web Development
Front End Web Development
Client-side Framework
React

Introduction

In this guide, you'll dive into learning about the very familiar this keyword. You may have worked with this a zillion times, but still not know how it works and how it affects your React components. You may also have assumed that the this keyword has to do a lot with React. But actually, it's just the way JavaScript binds the this context.

Understanding the this Reference

The this reference in JavaScript is identical to the this reference in other class-based languages like Java or C#. It points to which object is calling the function. In JavaScript, however, the this reference can be bound to different objects depending on where the function is being called. The this reference is also called as context.

The context or the this reference is by default bound to the global object when the function is called from the global scope.

1function bar() {
2  this.x = 43;
3}
4
5bar();
6console.log(x); // will log 43
js

Look at another example below.

1function bar() {
2  this.x = 43;
3}
4
5const barObject = {
6  barFn: bar
7};
8
9barObject.barFn();
10
11console.log(x); // will log undefined
12console.log(barObject.x); // will log 43
js

In this case, the bar() function is being called from the context of barObject object, so the this reference is bound to barObject. If you try to log the variable x, it will return undefined as the function bar() is not called from the global scope.

The bind() Function

You have probably come across the bind() function, which is used for binding the this reference of the class component to the event handlers. It looks something like this.

1class App extends React.Component {
2  constructor(props) {
3    super(props);
4    this.handleClick = this.handleClick.bind(this);
5  }
6  // ...
7}
js

The bind() function can be confusing, especially when you are just beginning with JavaScript or React. This section will explain what bind() does and how to use it.

Have a look at the example below .

1const User = {
2  lastName: "Wayne",
3  firstName: "Victor"
4};
5
6function logName() {
7  console.log(this.lastName, this.firstName);
8}
9
10logName(); // undefined, undefined
js

If you run the above code, the logName() function will console log undefined. That's because the value of the this reference is currently bound to the global object, and since there's no lastName or firstName variables defined in the global context, it returns undefined.

Now, bind the User object to the logName() function and watch the magic.

1const User = {
2  lastName: "Wayne",
3  firstName: "Victor"
4};
5
6function logName() {
7  console.log(this.lastName, this.firstName);
8}
9
10const userBoundLogName = logName.bind(User);
11
12userBoundLogName(); // Wayne Victor
js

Here, the bind() function binds the User object to the logName() function and returns a bounded function. The bounded function has the this reference pointing to the User object. You can create many references to the logName() function by binding to new objects, as shown below.

1const Victor = {
2  lastName: "Wayne",
3  firstName: "Victor"
4};
5
6const John = {
7  lastName: "Doe",
8  firstName: "John"
9};
10
11function logName() {
12  console.log(this.lastName, this.firstName);
13}
14
15const logVictor = logName.bind(Victor);
16const logJohn = logName.bind(John);
17
18logVictor(); // Wayne Victor
19logJohn(); // Doe John
js

This way, you don't have to pass arguments explicitly to the logName() function; instead, you can bind objects as you scale.

Using the setInterval() Method

Now that you have a good sense of the this keyword and the bind() function, take a look at how it can be used with setInterval() inside a component.

By default, the this reference will always be set to the global object. When working with class methods, you'll explicitly need to bind the this reference in order for the setInterval() function to reference the current class instance.

Take a look at a simple counterexample below.

1import React, { Component } from "react";
2
3class App extends Component {
4  state = { counter: 0 };
5
6  incrementCounter() {
7    const { counter } = this.state;
8    this.setState({ counter: counter + 1 });
9  }
10
11  componentDidMount() {
12    const thisBoundedIncrementer = this.incrementCounter.bind(this);
13    setInterval(thisBoundedIncrementer, 1000);
14  }
15
16  render() {
17    return (
18      <div className="App">
19        <h1>Counter</h1>
20        <h2>{this.state.counter}</h2>
21      </div>
22    );
23  }
24}
25
26export default App;
jsx

In the above code snippet, before passing the callback to the setInterval() function, you need to bind it to the current instance of the component. If you don't, the setInterval() callback won't have the context to this.state.

Hold on. There's an exception to the this reference in which you don't have to bind it to a function: when you use an arrow function.

In the above code, refactor the incrementCounter() function declaration to an arrow function.

1import React, { Component } from "react";
2
3class App extends Component {
4  state = { counter: 0 };
5
6  incrementCounter = () => {
7    const { counter } = this.state;
8    this.setState({ counter: counter + 1 });
9  };
10
11  componentDidMount() {
12    setInterval(incrementCounter, 1000);
13  }
14
15  render() {
16    return (
17      <div className="App">
18        <h1>Counter</h1>
19        <h2>{this.state.counter}</h2>
20      </div>
21    );
22  }
23}
24
25export default App;
jsx

In case of an arrow function, you don't have to bind the this reference. That's because an arrow function does not have a this reference in its context, and by default the this reference points to the class instance.

Conclusion

Using the this keyword and binding with the bind() function are fundamental concepts in JavaScript. You can bind any objects to a function and pass the this context. By default, this refers to the global object. Other than the bind() function, you can also use the call() or apply() method to change the value of the this reference.