Что-то меня озадачивает, поэтому, когда я определяю класс реагирующих компонентов, значения, содержащиеся в объекте this
, являются undefined в определенных методах (this
доступен в методах жизненного цикла) в классе, если я не использую .bind(this)
или определить метод, используя функцию стрелки, например, в следующем коде this.state
будет undefined в функции renderElements
, потому что я не определял его со стрелкой и не использовал .bind(this)
class MyComponent extends React.Component {
constructor() {
super();
this.state = { elements: 5 }
}
renderElements() {
const output = [];
// In the following this.state.elements will be undefined
// because I have not used .bind(this) on this method in the constructor
// example: this.renderElements = this.renderElements.bind(this)
for(let i = 0; i < this.state.elements; i ++){
output.push(<div key={i} />);
}
return output;
}
// .this is defined inside of the lifecycle methods and
// therefore do not need call .bind(this) on the render method.
render() {
return (
<div onClick={this.renderElements}></div>
);
}
}
Тогда в следующем примере мне не нужно использовать .bind(this)
или функцию стрелки, this
доступен, как ожидалось, в speak
function
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
var d = new Dog('Mitzie');
d.speak();
http://jsbin.com/cadoduxuye/edit?js,console
Чтобы уточнить, мой вопрос состоит из двух частей. Один), почему во втором примере кода мне не нужно вызывать .bind(this)
для функции speak
, но я делаю в компоненте React для функции renderElements
и Two), почему методы жизненного цикла (render, componentDidMount, и т.д.) уже имеют доступ к объекту класса this
, но renderElements
нет.
В документах React говорится следующее
[React Component Class] Методы следуют той же семантике, что и обычные классы ES6, что означает, что они автоматически не связывают это с экземпляром.
Но ясно, что они делают, как показывает второй пример кода, который я опубликовал.
Обновление
Обе ссылки в первых двух комментариях показывают рабочий пример классов React, не использующих .bind(this)
для методов класса, и он отлично работает. Но все же в документах явно указано, что вам нужно привязать свои методы или использовать функцию стрелки. В проекте с использованием gulp и babel я могу воспроизвести. Может ли это означать, что браузеры обновили?
Обновление 2
В моем первоначальном примере кода был this.renderElements()
, вызываемый непосредственно в функции рендеринга. Это будет работать, как ожидалось, без привязки функции или определения ее со стрелкой. Проблема возникает, когда я помещаю функцию в качестве обработчика onClick
.
Обновление 3
Проблема возникает, когда я помещаю функцию в качестве обработчика
onClick
.
На самом деле это не проблема. Контекст this
изменяется при передаче обработчику onClick, поэтому как работает JS.