назначение внутри объявления подкласса — React.Component

Я просматриваю учебник Egghead по React и на одном из уроков нашел следующее объявление класса:

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>
            )

        }
    }

Итак, глядя на код, мне было просто любопытно, что это за назначение вверху. Я просмотрел класс и расширил документацию по MDN, и там ничего не говорится о разрешении присваивания внутри объявления класса.

Кроме того, я попробовал это на примере кода, и он выдает ошибку:

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)
        }
    }

Итак... почему это работает?


person oquiroz    schedule 05.04.2018    source источник
comment
проверьте этот разницу между state = {} и конструктор(){....   -  person Mayank Shukla    schedule 05.04.2018
comment
Проблема в том, что в вашем тесте prop2 является свойством класса, поэтому попробуйте получить доступ к this.prop2 из render. Кроме того, что такое prop3вне конструктора?   -  person Tolsee    schedule 05.04.2018


Ответы (2)


Подкласс использует поля класса, которые являются шагом 3 и не являются частью существующих стандарт. Они обеспечивают синтаксический сахар для тела конструктора. Как объясняется в этом вопросе, существует определенный порядок, в котором выполняются назначения полей класса.

The subclass is identical to this ES6 class (check also вывод Babel, чтобы понять, что происходит):

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

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

console.log(prop2) относится к несуществующей переменной prop2, а не к свойству prop2.

Обратите внимание, что поскольку prop3 находится вне метода конструктора, он ссылается не на параметр конструктора prop3, а на некоторую несуществующую переменную prop3, поэтому параметр prop3_that_doesnt_collide и prop3 не конфликтуют.

Поскольку присваивание prop2 зависит от параметра конструктора, его следует поместить внутри метода конструктора:

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

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

Поскольку он просто сразу заменяет значение prop2 на prop3, это может быть:

constructor(prop1, prop2, prop3) {
    super(prop1, prop3);
}
person Estus Flask    schedule 05.04.2018

Синтаксис, который вы пытаетесь использовать, не стандартизирован, и вам понадобится Babel для переноса вашего кода. В качестве альтернативы вы можете использовать статические члены в классах -

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

console.log(Foo.staticData);
person Shobhit Chittora    schedule 05.04.2018
comment
Удивительно, но для разработки React вам понадобится Babel из-за JSX :) - person Estus Flask; 05.04.2018