2017-07-03 53 views
0
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()})') 
+1

'.on()'是一個回調嗎? 「sortedHighscores」爲空數組的原因可能是因爲你需要在'.on()'回調中設置狀態。 'setState'也可以是異步的,它的第二個參數有狀態完成設置時的回調。 –

回答

1

Data stored in a Firebase Realtime Database is retrieved by attaching an asynchronous listener to a database reference

按照documentation

因此,直到結果不知道,下面的代碼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

0

基本上你不會等待所有得分其設置的狀態,如果你把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?!?! 
} 
0

正如其他人所說,數據是從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()

+0

你好,我已經改變了我的代碼,並尋找進一步的指示。 console.log仍然給未定義 – chazefate

相關問題