У меня есть компонент React, который использует setInterval. Я хочу иметь возможность использовать компонент this внутри setInterval, но this становится окном внутри setInterval, а затем this становится undefined в обратном вызове.
Обе являются стрелочными функциями, поэтому для меня это кажется неожиданным, но, вероятно, есть внутренняя работа, о которой я пока не знаю.
Вот пример:
class MyComponent extends React.Component {
constructor(){
super()
this.hasEndedTimer = this.hasEndedTimer.bind(this)
...
this.hasEndedTimer(()=>{
// the callback 'this' is now undefined? Even though an arrow
function?
})
}
...
hasEndedTimer(callback) {
const intervalId = setInterval(() => {
// 'this' is now the window instead of the component? Even though arrow
if (somecondition()) callback()
}, 1000)
}
...
}
Могу ли я поддерживать контекст this компонента реакции внутри setInterval?
ПРИМЕЧАНИЕ. Если я изменю стрелочную функцию в setInterval на анонимную функцию, к которой я привязываю this, контекст this останется компонентом.
hasEndedTimer(callback) {
const intervalId = setInterval((function() {
// 'this' is now the component. Works as expected.
if (somecondition()) callback()
}).bind(this), 1000)
}
Извините, да, это был просто мой сокращенный синтаксис, чтобы показать пример. Это действительно происходит в коде. Я обновил выше, чтобы отразить. Я не верю, что реквизит требуется в конструкторе, если вы не передаете его в super.
Это обязательно, и неважно, используете ли вы реквизит или нет. Вы вызываете super, чтобы правильно инициализировать базовый класс компонента реакции, и он ожидает, что реквизиты будут в качестве первого параметра.
Интересно, потому что многие компоненты в нашем приложении просто вызывают super без передачи каких-либо свойств, когда мы не используем свойства в компоненте. Есть ли побочный эффект, которого мы не видим? Он определенно компилируется и работает так, как ожидалось. Приведенный выше пример подходит для выражения этого, поскольку в примере никогда не используются реквизиты и конструктор, а супер не вводит их.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Надеюсь, что это поможет вам.
Компонент реакции не имеет этого объекта выражения. Он должен получить его от родительского компонента, поэтому для его получения необходимо использовать super ().
Если вы забудете привязать this.handleClick и передать его, это будет неопределенным при фактическом вызове функции.
this.hasEndedTimer = this.hasEndedTimer.bind(this)
А при использовании стрелочной функции связывать (this) не нужно.
"This" обычно указывает на окно или глобальный объект. Когда он должен указывать на экземпляр класса, мы должны использовать привязку, чтобы привязать его к обратному вызову.
declare (){
console.info(...);
};
setInterval(this.declare.bind(this), 1000);
Итак, функция, которую вы устанавливаете внутри setInterval, на самом деле является функцией обратного вызова и может указывать на экземпляр класса. Таким образом, «this» работает хорошо.
Сама стрелочная функция не имеет этого, она должна наследовать от верхней части цепочки области видимости. И нет необходимости использовать привязку. В способах определения стрелочной функции this.hasEndedTime что-то не так.
this.hasEndedTimer = ()=>{
...
}
//how to use it
this.hasEndedTimer()
И setInterval в стрелочной функции должен обращать внимание на «this» внутри функции.
function Timer() {
this.s1 = 0;
setInterval(() => this.s1++, 1000);
}
var timer = new Timer();
setTimeout(() => console.info('s1: ', timer.s1), 3100);
Что касается конструктора, требующего привязки super и hasEnded в конструкторе, я просто оставил это в спешке, чтобы получить пример. Я обновил свой вопрос. Думаю, я до сих пор не понимаю, почему здесь не работает стрелочная функция вместо экземпляра класса?
@ user3331142 Я добавил кое-что о стрелочной функции.
Также
constructorдолжен принятьpropsв качестве аргумента и передать егоsuper(). А чтобы привязать функции к вашему экземпляру класса, вы должны либо объявить его в конструкторе с помощьюthis.myFunction =, либо в области действия класса с синтаксисом свойства класса. Вы могли это перепутать.