oquiroz
oquiroz

Reputation: 95

assignment inside subclass declaration - React.Component

I'm going through Egghead's React tutorial and in one of the lessons I found the following class declaration:

class StopWatch extends React.Component {
        state = {lapse: 0, running: false}

        render() {
            const {lapse, running} = this.state
            const buttonStyles = {
                border: '1px solid #ccc',
                background: '#fff',
                fontSize: '2em',
                padding: 15,
                margin: 5,
                width: 200
            }
            return (
                <div style={{textAlign: 'center'}}>
                    <label style={{fontSize: '5em', display: 'block'}}>
                        {lapse}ms
                    </label>
                    <button style={buttonStyles}>{running ? 'Stop' : 'Start'}</button>
                    <button style={buttonStyles}>Clear</button>
                </div>
            )

        }
    }

So looking at the code, I was just curious about that assignment on the top. I looked at the class and extends documentations on MDN and it doesn't say anything about allowing an assignment inside a class declaration.

Furthermore, I tried it on a sample code and it's throwing an error:

class Square {
        constructor(prop1, prop2) {
            this.prop1 = prop1
            this.prop2 = prop2
        }
    }

    class Polygon extends Square {
        constructor(prop1, prop2, prop3) {
            super(prop1, prop2)
        }
        prop2 = prop3
        render() {
            console.log(prop2)
        }
    }

So... why does it work?

Upvotes: 1

Views: 158

Answers (2)

Estus Flask
Estus Flask

Reputation: 222979

The subclass uses class fields which are stage 3 proposal and aren't a part of existing standard. They provide syntactic sugar for constructor body. As explained in this question, there's a specific order in which class field assignments are performed.

The subclass is identical to this ES6 class (check also Babel output to get some ideas what's going on):

class Polygon extends Square {
    constructor(prop1, prop2, prop3_that_doesnt_collide) {
        super(prop1, prop2);
        this.prop2 = prop3;
    }

    render() {
        console.log(prop2)
    }
}

console.log(prop2) refers to non-existing prop2 variable and not prop2 property.

Notice that because prop3 was located outside constructor method, it doesn't refer to prop3 constructor parameter but to some non-existing prop3 variable, so prop3_that_doesnt_collide parameter and prop3 don't collide.

Since prop2 assignment relies on constructor parameter, it should be placed inside constructor method:

class Polygon extends Square {
    constructor(prop1, prop2, prop3) {
        super(prop1, prop2);
        this.prop2 = prop3;
    }

    render() {
        console.log(this.prop2)
    }
}

Since it just immediately replaces prop2 value with prop3, it can be:

constructor(prop1, prop2, prop3) {
    super(prop1, prop3);
}

Upvotes: 1

Shobhit Chittora
Shobhit Chittora

Reputation: 1279

The syntax you're trying to use is not standardized and you'll need Babel to transpile your code. Alternatively you can use static members in classes -

let Foo = class {
  static get staticData() {
    return 'Static Data';
  }
}

console.log(Foo.staticData);

Upvotes: 0

Related Questions