DEV Community

Cover image for Why Should You Use Transform Class Properties Plugin
Maksim Ivanov
Maksim Ivanov

Posted on

Why Should You Use Transform Class Properties Plugin

Originally posted on maksimivanov.com

In my previous post I used pretty interesting syntax to define class methods for my Popup component. I was able to use arrow functions to change the scope of this to class level. Hmm, but it's not actually Javascript, so how did I do that?

First let's refresh your memory, i'm talking about this code:

import React, { Component } from 'react';
import Popup from './Popup';
import SubscriptionForm from './SubscriptionForm';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = { isOpen: false };
  }

  openPopup = () => {
    this.setState({
      isOpen: true
    });
  }

  closePopup = () => {
    this.setState({
      isOpen: false
    });
  }

  render() {
    return (
      <div className="App">
        <button onClick={this.openPopup}>
          Click Me!
        </button>

        <Popup show={this.state.isOpen}
          onClose={this.closePopup}>
          <SubscriptionForm></SubscriptionForm>
        </Popup>
      </div>
    );
  }
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Look, at the openPopup for example. That openPopup = is exactly what transform-class-properties allowed me to do.

openPopup = () => {
  this.setState({
    isOpen: true
  });
}
Enter fullscreen mode Exit fullscreen mode

Also it allowed me to use arrow function here. If not it this in that function would reference global scope instead of the scope of App class. Probably I would get an error like Uncaught TypeError: Property 'setState' of object [object Object] is not a function.

But What Are The Alternatives

More traditional and verbose approach would be to bind this manually. You can do this inside the constructor method.

  constructor(props) {
    super(props);

    this.openPopup = this.openPopup.bind(this);
    this.closePopup = this.closePopup.bind(this);
    this.state = { isOpen: false };
  }
Enter fullscreen mode Exit fullscreen mode

You have to do this for every funcion that will use this reference, and it's very repetitive.

You Can Bind In Render Function

For example by using bind(this):

<button onClick={this.openPopup.bind(this)}>
Enter fullscreen mode Exit fullscreen mode

Or by using arrow functions:

<button onClick={e => this.openPopup(e)}>
Enter fullscreen mode Exit fullscreen mode

Both of these require additional hassle, look ugly and have performance implications as you basically reallocate the function on every render.

Summary

This is why you better use class level properties. And by the way there is a proposal about class fields for future JS versions and it's already Stage 3. That means that it's very likely to become part of the language.

If you are interested in learning new Javascript features (maybe even ones that are not included yet) – make sure to subscribe to my mailing list:

example button
Here this button is just an image, go to maksimivanov.com to see the real one

Top comments (0)