Я читаю руководство по стилю javascript air-bnb, и в нем говорится, что этого делать не следует:
23.5 Не сохраняйте ссылки на это. Используйте стрелочные функции или Function#bind.
// bad
function foo() {
const self = this;
return function () {
console.info(self);
};
}
// bad
function foo() {
const that = this;
return function () {
console.info(that);
};
}
// good
function foo() {
return () => {
console.info(this);
};
}
Я уже провел некоторое исследование и нашел два ответа здесь, в stackoverflow, но принятый ответ в одном из них заключается в том, что это нельзя обойти:
а другой предлагает использовать привязку, но предлагает использовать функцию генератора.
Вложенная ссылка на this в классах ES6
Я создаю приложение ReactJS, и мне нужно получить доступ к setState из Firebase Promise.
saveSessionToDB = () => {
const that = this;
db.collection("sessions")
.add({
props: MyProps
})
.then(function(docRef) {
console.info("Session written with ID: ", docRef.id);
that.setState({ sessionID: docRef.id });
})
.catch(function(error) {
console.error("Error adding document: ", error);
that.setState({ sessionError: error });
});
}
Я старался
const {setState} = this;
а потом
setState({sessionID:docRef.id});
но я получаю сообщение об ошибке.
Я безуспешно пытался связать saveSessionToDB в конструкторе, даже если это функция стрелки.
Есть ли другой способ сделать это или я должен просто принять, что иногда мне все равно придется писать const that = this?
@ritaj это функция стрелки.
@RobG почти все правила ESLint не имеют «доказательства» того, что они плохие, но в основном являются стандартами кодирования. Хорошо сохранять их, плохо отклоняться, даже если вы можете добиться того же самого с другим кодом/синтаксисом/форматированием.
@guergana не то, на что ты переходишь .then
.then(function(docRef) {} ) это не функция стрелки.
да, только что заметил. Спасибо!
@VLAZ — да, смотрите документация. ESLint не предписывает, что «хорошо» или «плохо», это просто набор правил, которые можно использовать для проверки стиля кодирования, т. Е. То, что у него есть правило, не означает, что соблюдение этого правила является хорошей идеей в целом. Документация включает рекомендации, когда не следует использовать определенные правила (например, недействительный-это).
@RobG, это ... то, что я сказал. Правила ESLint предназначены только для обеспечения соблюдения стандартов кодирования. Следовательно, это не «хорошо» и не «плохо».
@VLAZ - конечно, упустил твою мысль. :-) Но это подтверждает, что Airbnb должен объяснить, почему это и себя не следует использовать (мне действительно все равно, я просто думаю, что они должны объяснить, почему они настаивают на определенном стиле кодирования).



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


Вы также должны использовать функции стрелок для then и catch:
saveSessionToDB = () => {
db.collection("sessions")
.add({ props: MyProps })
.then((docRef) => {
console.info("Session written with ID: ", docRef.id);
this.setState({ sessionID: docRef.id });
})
.catch((error) => {
console.error("Error adding document: ", error);
this.setState({ sessionError: error });
});
}
Причина, по которой стрелочные функции полезны, заключается в том, что они не имеют собственного контекста this (или arguments), поэтому они берут this из своего внешнего лексического окружения. Вот почему вы можете использовать this компонента внутри функции стрелки.
Используйте стрелочные функции для внутренних функций:
.then(docRef => {
console.info("Session written with ID: ", docRef.id);
this.setState({ sessionID: docRef.id });
})
.catch(error => {
console.error("Error adding document: ", error);
this.setState({ sessionError: error });
});
Или используйте bind:
.then(function(docRef) {
console.info("Session written with ID: ", docRef.id);
that.setState({ sessionID: docRef.id });
}.bind(this))
.catch(function(error) {
console.error("Error adding document: ", error);
that.setState({ sessionError: error });
}.bind(this));
В промисах, которые используются на экранах/компонентах и даже, в основном за пределами синтаксиса реакции в методе then() и catch(), вы обычно отправляете функцию стрелки (в контексте выборки ничего не стоит), поэтому вы сохраняете контекст снаружи (В данном случае контекст React.Component).
В вашем случае всего с двумя фиксами (стрелочная функция и что к этому) все работает:
saveSessionToDB = () => {
const that = this;
db.collection("sessions")
.add({
props: MyProps
})
.then((docRef) => { // arrow function
console.info("Session written with ID: ", docRef.id);
this.setState({ sessionID: docRef.id }); // that => this
})
.catch((error) => { // arrow function
console.error("Error adding document: ", error);
this.setState({ sessionError: error }); // that => this
});
}
Почему бы вам просто не использовать стрелочные функции?