Как избежать создания ссылок «this» в ES6: const that = this, если область действия вложена в React - PullRequest
1 голос
/ 03 июля 2019

Я читаю руководство по стилю javascript air-bnb, в котором говорится, что этого делать не следует:

23.5 Не сохраняйте ссылки на это. Используйте функции стрелок или функцию # связать.

// bad
function foo() {
  const self = this;
  return function () {
    console.log(self);
  };
}

// bad
function foo() {
  const that = this;
  return function () {
    console.log(that);
  };
}

// good
function foo() {
  return () => {
    console.log(this);
  };
}

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

ES6 избегать этого / self

, а другой предлагает использовать связывание, но он предложил использовать функцию генератора.

Вложенная ссылка на `this` в классах ES6

Я создаю приложение ReactJS, и мне нужно получить доступ к setState из Promise в Firebase.

   saveSessionToDB = () => {
        const that = this;
        db.collection("sessions")
          .add({
            props: MyProps
          })
          .then(function(docRef) {
            console.log("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, что = this?

Ответы [ 3 ]

3 голосов
/ 03 июля 2019

Вы должны использовать функции стрелок и для then и catch:

saveSessionToDB = () => {
  db.collection("sessions")
    .add({ props: MyProps })
    .then((docRef) => {
      console.log("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 внутри функции стрелки.

1 голос
/ 03 июля 2019

В обещаниях, которые используются на экранах / компонентах и ​​даже в большинстве случаев вне синтаксиса реагирования в методах then () и catch (), вы обычно отправляете функцию стрелки (в контексте выборки ничего не стоит), поэтому вы сохраняетеконтекст извне (в данном случае контекст React.Component).

В вашем случае всего два исправления (функция со стрелкой и тому подобное) все работает:

saveSessionToDB = () => {
        const that = this;
        db.collection("sessions")
          .add({
            props: MyProps
          })
          .then((docRef) => { // arrow function
            console.log("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
          });
}
1 голос
/ 03 июля 2019

Используйте функции стрелок для внутренних функций:

.then(docRef => {
  console.log("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.log("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));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...