В чем разница между использованием конструктора vs state = {} для объявления состояния в компоненте реакции?

Я обнаружил, что существует два способа объявить состояние в классе, например, ниже

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'John'
        }
    }

    render() {
        return  <div>{this.state.name}</div>
    }

}

а также

class App extends Component {
    state = {
       name: 'John'
    }

    render() {
        return  <div>{this.state.name}</div>
    }

}

В чем разница между этими двумя?

Ответ 1

Они примерно эквивалентны. Существенное различие заключается в том, что инициализатор во втором примере выполняется перед constructor.

Второй подход использует предложение полей классов.

Он еще не является частью стандарта ECMAScript, поэтому вам необходимо правильно настроить транспилятор, чтобы использовать второй подход.

UPD Взгляните на вывод Babel, чтобы лучше понять, как работают поля общих экземпляров.

Ответ 2

Используйте конструктор, если вы хотите сохранить данные props в state

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      name: 'John'
    }
  }
}

В противном случае вы можете напрямую установить state для жестко закодированных данных

class App extends Component {
  state = {
    name: 'John'
  }
}

Ответ 3

Когда вы добавляете метод в класс, он фактически добавляется в прототип функции. вот так:

class Same{
  thing() {}
}

// Equivalent to:

function Same() {}
Same.prototype.thing = function () {}

вещь определяется один раз и распределяется между всеми экземплярами класса.

Если вы реорганизуете его для использования полей классов следующим образом:

class Animal {
  thing() {}
  anotherThing = () => {} // Class Field
}

// Equivalent to:

function Animal () {
  this.anotherThing = function () {}
}

Animal.prototype.thing = function () {}

anotherThing определяется для каждого вновь создаваемого экземпляра, а не для прототипа.

Опыт разработки против производительности

Это компромисс, который вы должны рассмотреть. Class Fields делает ваш код выглядит читабельным и чистым. Однако в полях классов хранится копия anotherThing в каждом из ваших экземпляров.

Поэтому вам следует тщательно подумать, хотите ли вы их использовать.