Реакция ES6: будут ли методы @autobind ES.Next связывать методы только один раз для каждого экземпляра?

Есть много вопросов / статей, написанных о многочисленных способах обработки связывания в ES6 React, но большинство из них, похоже, не решают проблему, описанную в документах React (выделено мое):

Мы рекомендуем вам связать ваши обработчики событий в конструкторе, чтобы они были связаны только один раз для каждого экземпляра:

constructor(props) {
  super(props);
  this.state = {count: props.initialCount};
  this.tick = this.tick.bind(this);
}

Для контекста, они советуют против встроенной привязки методов, таких как:

//using .bind()
<div onClick={this.tick.bind(this)}>

// ES6 anon arrow functions
<div onClick={() => this.tick()}>

// ES.Next :: operator
<div onClick={::this.tick}>

Конечно. Но рекомендуемое решение для привязки каждого метода в конструкторе является громоздким с большим количеством методов, поэтому я рассматривал декоратор ES.Next @autobind на уровне класса как простое решение:

import { autobind } from 'core-decorators';

@autobind
class Person {
  getPerson() {
    return this;
  }

  getPersonAgain() {
    return this;
  }
}

let person = new Person();
let { getPerson, getPersonAgain } = person;

getPerson() === person;
// true

getPersonAgain() === person;
// true

Чего я не могу понять, так это того, будет ли у этого декоратора тот же недостаток встроенных методов привязки? то есть методы будут связаны только один раз для каждого экземпляра?

Если нет, есть ли краткое решение, которое позволяет избежать этой ловушки?

2 ответа

Поля экземпляра класса и связанные с ними инициализаторы решают проблему необходимости присваивать свойства с тем же именем, что и методы внутри конструктора, но с более кратким синтаксисом. Следующий пример возможен с преобразованием свойств класса Babel:

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }
  tick = () => {
    this.setState({count: this.state.count + 1});
  };
  ...
 }

Это создает новый, связанный tick свойство для каждого Counter пример. Это создает столько же связанных функций, сколько React.createClass сделал.

Без поля экземпляра и инициализатора эффект одинаков (ограничение tick свойство создается для каждого Counter экземпляр), но с более подробным синтаксисом:

constructor(props) {
  super(props);
  this.state = {count: props.initialCount};
  this.tick = this.tick.bind(this);
}
tick() {
  this.setState({count: this.state.count + 1});
}

Я написал небольшой компонент, который связывает все методы других компонентов. Вы можете попробовать это, если хотите: http://www.marouen-mhiri.com/react/autobinding-es6-classes-in-react-another-approach/

Другие вопросы по тегам