【问题标题】:How to avoid creating references of 'this' in ES6: const that = this when scope nested in React如何避免在 ES6 中创建“this”的引用:当范围嵌套在 React 中时,const that = this
【发布时间】:2019-11-13 23:43:42
【问题描述】:

我正在阅读 air-bnb javascript 样式指南,它说不应该这样做:

23.5 不要保存对此的引用。使用箭头函数或 Function#bind。

// 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 avoid that/self

另一个建议使用绑定,但它建议使用生成器函数。

Nested reference to `this` in ES6 classes

我正在构建一个 ReactJS 应用程序,我需要从 firebase Promise 中访问 setState。

   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 that = this?

【问题讨论】:

  • 为什么不直接使用箭头函数?
  • 你可能会让他们想起Hitchens's razor为什么不好?
  • @ritaj 这是一个箭头函数。
  • .then(function(docRef) {} ) 这不是箭头函数。
  • @VLAZ——当然,错过了你的意思。 :-) 但它强调 Airbnb 应该解释为什么不应该使用 thatself (我真的不在乎,我只是认为他们应该解释为什么他们坚持特定的编码风格)。

标签: javascript reactjs function ecmascript-6 scope


【解决方案1】:

thencatch 也必须使用箭头函数:

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

【讨论】:

    【解决方案2】:

    对内部函数使用箭头函数:

    .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));
    

    【讨论】:

      【解决方案3】:

      在屏幕/组件上使用的 Promise 中,甚至大部分在 then() 方法和 catch() 中的 react 语法之外,您通常会发送一个箭头函数(在 fetch 上下文中没有任何价值),因此您可以保留来自外部的上下文(在本例中为 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
                });
      }
      

      【讨论】:

        猜你喜欢
        • 2018-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-04
        • 2023-03-29
        • 2010-10-01
        相关资源
        最近更新 更多