ComponenWillMount发生后出于某种原因回应原生
componentDidMount() {
const refi = database.ref("highscores");
// Pushing sorted data to highscoreArray.
refi.orderByChild("highscore").limitToLast(3).on("value", function(snapshot) {
sortedHighscores = [];
snapshot.forEach(function(child) {
sortedHighscores.push({
"username" : child.val().username,
"score" : child.val().highscore
});
});
sortedHighscores.sort(function(a,b) {
return a.score - b.score;
});
this.setState({highscoreArray : sortedHighscores.reverse()});
});
console.log("highscore is:", this.state.highscoreArray);
}
我想从数据库中获取数据并将其放入highscoreArray中。然后我试图把它作为一个文本渲染。有些原因是空的或空的。这意味着componentWillMount()发生在渲染后()ComponenWillMount发生后出于某种原因回应原生
有人可以解释或使这项工作?我很沮丧。
我已经改变了代码,因为人们帮助我,但它仍然是给错误:
undefined is not a function (evaluating 'this.setState({ highscoreArray:sortedHighscores.reverse()})')
Data stored in a Firebase Realtime Database is retrieved by attaching an asynchronous listener to a database reference
因此,直到结果不知道,下面的代码this.state.highscoreArray[0]["score"].toString()
将返回一个错误。在显示结果之前,请检查highscoreArray
是否包含一些项目。
此外,检索数据不是一个好习惯。看看到React component lifecycle:
componentWillMount() is invoked immediately before mounting occurs. It is called before render(), therefore setting state synchronously in this method will not trigger a re-rendering. Avoid introducing any side-effects or subscriptions in this method
基本上你不会等待所有得分其设置的状态,如果你把componentWillMount到一个异步函数,我相信它会解决你的问题之前,要推:
async componentWillMount() {
sortedHighscores = [];
const refi = database.ref("highscores");
// Pushing sorted data to highscoreArray.
await refi.orderByChild("highscore").limitToLast(3).on("child_added", function(snapshot) {
sortedHighscores.push({
"username" : snapshot.val().username,
"score" : snapshot.val().highscore});
});
sortedHighscores.sort(function(a,b) {
return a.score - b.score;
});
this.setState({highscoreArray : sortedHighscores.reverse()});
console.log("highscorevvvvv", sortedHighscores);//this.state.highscoreArray) // these are EMPTY?!?!
}
正如其他人所说,数据是从Firebase异步读取的。在读取数据的同时,您可以使用空数组调用setState()
。然后当数据返回时,将其添加到数组中,但不再调用setState()
。
的解决方案是将呼叫转移到setState()
成火灾时,数据已被读取(或改变)回调:
refi.orderByChild("highscore").limitToLast(3).on("value", function(snapshot) {
sortedHighscores = [];
snapshot.forEach(function(child) {
sortedHighscores.push({
"username" : child.val().username,
"score" : child.val().highscore
});
});
sortedHighscores.sort(function(a,b) {
return a.score - b.score;
});
this.setState({highscoreArray : sortedHighscores.reverse()});
});
你会注意到,我听一个value
事件,确保我一口气拿到3分。在添加分数之前,我也清除了这个数组,因为这个value
回调将在最后3个分数改变时被调用。所以这意味着您的分数会在UI中自动更新,例如当您在Firebase Database console中更改分数时。尝试一下。好有趣!
鉴于Andrew和Hennek的答案,您可能需要将此代码放入componentDidMount()
。但是,您也需要在回调中拨打setState()
。
你好,我已经改变了我的代码,并寻找进一步的指示。 console.log仍然给未定义 – chazefate
'.on()'是一个回调吗? “sortedHighscores”为空数组的原因可能是因为你需要在'.on()'回调中设置状态。 'setState'也可以是异步的,它的第二个参数有状态完成设置时的回调。 –