DEV Community

tiff
tiff

Posted on

How to Bind 'this' in React Without a Constructor

This post was originally on my blog.

this in React is a reference to the current component. Usually this in React is bound to its built-in methods so that when you want to update state or use an event handler on a form, you could do something like this:

<input type="text" ref={this.someInput} required placeholder="This is a Method" defaultValue={getSomeMethod()}/>
Enter fullscreen mode Exit fullscreen mode

where this.someInput is passing state to whichever React component you are rendering.

Unfortunately, though, React doesn't auto-bind this to custom methods. This means if I wanted to manipulate the DOM by getting some input, which you can't do as you can with normal JavaScript, I would create a ref to do whatever DOM tinkering I wanted.

But because React doesn't auto-bind this, the following code would output undefined when logged:

someInput = React.createRef();
  renderSomeInput (event) {
    event.preventDefault();
    const someFunction = this.someInput.current.value;
    console.log(this);
  }
Enter fullscreen mode Exit fullscreen mode

In order to avoid this, we could use the constructor function in order to render the component or get the state we want:

class SomeCompenent extends React.Component {
   constructor() {
    super();
    this.renderSomeInput.bind(this);
   }
}
Enter fullscreen mode Exit fullscreen mode

While this is a decent way to render a ref on a component, what if you wanted to bind several custom methods in one component? It would get pretty messy...

class SomeCompenent extends React.Component {
   constructor() {
    super();
    this.renderSomeInput.bind(this);
    this.renderSomeInput.bind(this);
    this.renderSomeInput.bind(this);
    this.renderSomeInput.bind(this);
   }
}
Enter fullscreen mode Exit fullscreen mode

You get the idea.

Instead, we can bind this to custom React methods by declaring a method by assigning it to an arrow function:

class SomeCompenent extends React.Component {

someInput = React.createRef();
  renderSomeInput = (event) =>  {
    event.preventDefault();
    const someFunction = this.someInput.current.value;
    console.log(this);
  }
}
Enter fullscreen mode Exit fullscreen mode

which will allow us to bind the value of this to the SomeComponent component.

Hope This Helps!

ES6 gave us classes and constructors and React utilized them right away. You don't always need a constructor, and it helps to know when to use one and when not to.

Top comments (4)

Collapse
 
joelnet profile image
JavaScript Joel

In your "messy" example, I believe the code should be even messier. The bind won't mutate the original function, but will return a new and bound function. So you must also set this to overwrite the original function.

class SomeCompenent extends React.Component {
   constructor() {
    super();
    // this does not modify the original function
    this.renderSomeInput.bind(this);

    // this binds the original function
    this.renderSomeInput = this.renderSomeInput.bind(this);
   }
}
Collapse
 
dmerand profile image
Donald Merand

This is great!

Collapse
 
tifflabs profile image
tiff

Thanks @dmerand . It is a work in progress. I was trying to synthesize what I wanted to say and it didn't quite come out like I wanted. Working on it though!

Collapse
 
dmerand profile image
Donald Merand

I think it was pretty clear! It also shows a larger point about arrow functions and how they can be used strategically in situations like this where you need to be careful about which object is getting bound to a function.