反应:无法读取未定义的属性“ setState”

问题描述

我从Firebase实时数据库中获得了一些数据,现在我正尝试将其添加到变量中。我确信查询有效,因为如果我console.log(dataSnapshot)它将记录正确的数据(即001)。但是,当我尝试使用该数字创建变量时,出现以下错误无法读取未定义的属性'setState',并且它不会向控制台返回任何内容

这是我的代码

class Table extends Component {
  constructor(props) {
    super(props);
    this.state = { timestamps: [],user: auth().currentUser,serial: "" };
  }

  componentDidMount() {
    const uid = this.state.user.uid;
    console.log(uid);
    let serial = this.state.serial;
    const serialRef = db.ref(uid + "/serial");
    serialRef.once("value").then(function (dataSnapshot) {
      console.log(dataSnapshot.val());
      this.setState({ serial: dataSnapshot.val() },() => {
        serial = this.state.serial;
        console.log(serial);
      });
    });

Here's the screenshot of my console

谢谢!

解决方法

您没有使用箭头回调函数,如果不使用箭头回调,则必须绑定您的函数。如果您不想编写bind语句,请使用arrow函数,该函数将自动获取类的上下文。

serialRef.once("value").then((dataSnapshot) => {
      console.log(dataSnapshot.val());
      this.setState({ serial: dataSnapshot.val() },() => {
        serial = this.state.serial;
        console.log(serial);
      });
    });

,

您的问题是传递给serialRef.once("value").then(...)的回调没有设置"this" context。如果将代码更改为此,它应该可以工作:

componentDidMount() {
    const uid = this.state.user.uid;
    console.log(uid);
    let serial = this.state.serial;
    const serialRef = db.ref(uid + "/serial");
    // grab a reference to the current "this" context
    const table = this;
    serialRef.once("value").then(function (dataSnapshot) {
      console.log(dataSnapshot.val());

      // invoke setState on the captured context
      table.setState({ serial: dataSnapshot.val() },() => {
        serial = table.state.serial;
        console.log(serial);
      });
    });

或者您可以使用lambda函数,就像您已经在setState调用中完成

componentDidMount() {
    const uid = this.state.user.uid;
    console.log(uid);
    let serial = this.state.serial;
    const serialRef = db.ref(uid + "/serial");
     // "Fat arrow" or "lambda" functions implicitly capture the current "this" context
    serialRef.once("value").then((dataSnapshot) => {
      console.log(dataSnapshot.val());
      this.setState({ serial: dataSnapshot.val() },() => {
        serial = this.state.serial;
        console.log(serial);
      });
    });
,

箭头功能应保留您的此上下文

serialRef.once("value").then((dataSnapshot) => {
     console.log(dataSnapshot.val());
     this.setState({ serial: dataSnapshot.val() },() => {
       serial = this.state.serial;
       console.log(serial);
     });