我的应用程序从Firebase Realtime数据库检索数据,并尝试以“状态”加载数据,但收到错误消息“无法读取未定义的属性setState
”。
我试图在构造函数中添加绑定,但这不起作用
import React from 'react';
import { View } from '@vkontakte/vkui';
import * as firebase from "firebase/app";
import {config} from './dbinit' // import firebase config
import "firebase/database";
import Home from './panels/Home';
class App extends React.Component {
constructor(props) {
super(props);
this.setState = this.setState.bind(this);
this.state = {
activePanel: 'home',
db: null,
loading: true,
};
console.log("init");
}
componentDidMount = () => {
let ref = firebase
.initializeApp(config)
.database()
.ref();
ref.once("value").then(function onSuccess(res) {
console.log("success", res.val())
this.setState({db: res.val(), loading: false})
// ERROR GOES HERE 'Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined'
});
}
go = (e) => {
this.setState({activePanel: e.currentTarget.dataset.to})
};
render() {
const { loading, db } = this.state;
return loading ? (
<div>loading...</div>
) : (
<View activePanel={this.state.activePanel}>
<div>loaded</div>
</View>
);
}
}
export default App;
我希望setState
可以正常工作,但实际有错误Cannot read property 'setState' of undefined'
答案 0 :(得分:1)
您从那以后就失去了背景。使用的功能:
ref.once("value").then(function onSuccess(res) {
console.log("success", res.val())
this.setState({db: res.val(), loading: false})
// ERROR GOES HERE 'Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined'
});
使用箭头功能可以这样:
ref.once("value").then((res) => {
console.log("success", res.val())
this.setState({db: res.val(), loading: false})
// ERROR GOES HERE 'Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined'
});
答案 1 :(得分:0)
原因是因为您使用的是基于被调用方而不是基于词法作用域动态绑定this关键字的常规函数,因为此代码在严格模式下运行(因为它在类中),因此this关键字被解析为未定义。
如果您想保留上下文,则必须绑定该函数或使用箭头函数(根据词汇范围绑定此关键字)
转换此
ref.once("value").then(function onSuccess(res) {
console.log("success", res.val())
this.setState({db: res.val(), loading: false})
// ERROR GOES HERE 'Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined'
});
对此
ref.once("value").then(res => this.setState({db: res.val(), loading: false}));
答案 2 :(得分:-1)
从箭头功能的使用中,我看到您的Babel配置能够处理类字段的较新(即将发布)的ES功能,因此完全摆脱您的构造函数可能是值得的。
class App extends React.Component {
state = {
activePanel: 'home',
db: null,
loading: true,
};
componentDidMount = () => {
....
这不能回答问题,但我想提一提:)
维克多(Viktor)的答案提到,由于不使用箭头功能,您的'this'上下文丢失了。