2016-11-15 153 views
0

我有以下火力數據庫:ReactJS狀態得到恢復

enter image description here

我想要一個反應腳本,通過數據庫的位置去和表徵數據。這是我的嘗試。

我創建了這些以下狀態:

allExperts: [ 
     [] // holds arrays of expert records 
    ], 


    feat_experts: [ 
     [] // stores arrays of featured experts 
    ], 

    new_experts: [ 
     [] // stores arrays of new experts 
    ] 
}; 

然後,我創造了這個下面的方法填充百科首頁狀態:

loadAllExperts(){ 
     var thisApp = this; 
     // All Experts 
     const rootRef = firebase.database().ref().child('experts'); 
     rootRef.once('value', snap => { 
      var allExperts = []; 
      snap.forEach(function(child){ 
       var queueExpert = []; 
       child.forEach(function(g_child){ 
        queueExpert.push(g_child.val()); 

       }); 
       allExperts.push(queueExpert); 
      }); 
      thisApp.setState({ 
       allExperts: allExperts 
      }); 
      console.log(this.state.allExperts); 

     }); 
     this.refineFeatured(); 
    } 

我認爲這將填充任何從數據庫中獲取百科首頁。 console.log()方法按照我希望的方式打印數組。

現在我想改進allExperts狀態,以便我只獲得精選專家。我用下面的方法做:

refineFeatured(){ 
     var allExperts = this.state.allExperts; 
     console.log(allExperts); 

     var allFeatExperts = []; 
     var row = this.state.allExperts.length; 

     for(var i = 0; i < row; i++){ 
      if(allExperts[i][5] === "featured"){ 
       allFeatExperts.push(allExperts[i]); 
      } 
     } 
     this.setState({ 
      feat_experts: allFeatExperts 
     }); 
    } 

,該執行console.log()方法打印一個空數組,所以它沒有正確填充在loadAllExperts百科首頁()。

這裏是整個代碼:

import React, { Component } from 'react'; 
import '../App.css'; 
import './Tab.css'; 
import { Tabs, Tab, Button } from 'react-bootstrap'; 
import * as firebase from 'firebase'; 

class App extends Component { 


    constructor(props) { 

     super(props); 
     this.state = { 
      key: 1, 

      /* 
      * 
      * allExperts: [ 
      * 
      * [email,message,name,occupation,phone,position], 
      * [...] 
      * 
      * ] 
      * 
      * 
      * */ 
      allExperts: [ 
       [] 
      ], 


      feat_experts: [ 
       [] 
      ], 

      new_experts: [ 
       [] 
      ], 

      pop_experts: [ 
       [] 
      ] 
     }; 

     this.handleSelect = this.handleSelect.bind(this); 
     this.loadAllExperts = this.loadAllExperts.bind(this); 
     this.refineNew = this.refineNew.bind(this); 

     this.loadAllExperts(); 

    } 

    handleSelect(key) { 
     this.setState({key}); 
    } 


    loadAllExperts(){ 
     var thisApp = this; 
     // All Experts 
     const rootRef = firebase.database().ref().child('experts'); 
     rootRef.once('value', snap => { 
      var allExperts = []; 
      snap.forEach(function(child){ 
       var queueExpert = []; 
       child.forEach(function(g_child){ 
        queueExpert.push(g_child.val()); 

       }); 
       allExperts.push(queueExpert); 
      }); 
      thisApp.setState({ 
       allExperts: allExperts 
      }); 
     }); 
     this.refineFeatured(); 
    } 

    refineFeatured(){ 
     var allExperts = this.state.allExperts; 
     console.log(allExperts); 

     var allFeatExperts = []; 
     var row = this.state.allExperts.length; 

     for(var i = 0; i < row; i++){ 
      if(allExperts[i][5] === "featured"){ 
       allFeatExperts.push(allExperts[i]); 
      } 
     } 
     this.setState({ 
      feat_experts: allFeatExperts 
     }); 
    } 

    refineNew(){ 
     var allExperts = this.state.allExperts; 
     var allNewExperts = []; 
     var row = this.state.allExperts.length; 

     for(var i = 0; i < row; i++){ 
      if(allExperts[i] === "new"){ 
       allNewExperts.push(allExperts[i]); 
      } 
     } 
     this.setState({ 
      new_experts: allNewExperts 
     }); 
    } 



    render() { 
     return (
      <div> 
       <Button onClick={this.loadAllExperts}>Load Experts</Button> 
       <div className="container browseArea"> 
        <div className="col-lg-12"> 
         <div className="col-lg-12"> 
          <Tabs activeKey={this.state.key} onSelect={this.handleSelect} id="controlled-tab-example" onLoad={this.loadAllExperts}> 
           <Tab eventKey={1} title="Featured" className="tab-ind"> 
            { allFeatExperts.map(function(exp, index){ 
             return(
              <div key={index}> 
               <div className="col-lg-12"> 
                <div className="col-lg-2"> 
                 <div className="well"> 
                  <img className="img-responsive" alt="alt-message0" 
                   src="http://placehold.it/350x150"/> 
                 </div> 
                </div> 
                <div className="col-lg-7"> 
                 <div className="well"> 
                  {/*email,message,name,occupation,phone,position*/} 
                  <strong>Get Top Tier PR Media Exposure of Your Company for 
                   Free.</strong><br/> 
                  <span className="text-muted">{ exp[2] } • Los Angeles and Ottawa Canada</span><br /> 
                  <span className="description">{ exp[1] }</span> 

                 </div> 
                </div> 
                <div className="col-lg-3"> 
                 <span className="price"> 
                  <div className="input-group"> 
                   <span className="input-group-addon" id="basic-addon1">$5/min</span> 
                   <input type="button" className="form-control btn-success" value="Request a call" placeholder="Username" aria-describedby="basic-addon1"/> 
                  </div> 
                 </span> 
                </div> 
               </div> 
               <div className="col-lg-12"> 
                <hr className="step-divider"/> 
               </div> 
              </div> 
             ) 
            }) 

            } 


           </Tab> 
           <Tab eventKey={2} title="New" className="tab-ind" onClick={this.refineNew}> 

            { allNewExperts.map(function(exp, index){ 
             return(
              <div key={index}> 
               <div className="col-lg-12"> 
                <div className="col-lg-2"> 
                 <div className="well"> 
                  <img className="img-responsive" alt="alt-message0" 
                   src="http://placehold.it/350x150"/> 
                 </div> 
                </div> 
                <div className="col-lg-7"> 
                 <div className="well"> 
                  {/*email,message,name,occupation,phone,position*/} 
                  <strong>Get Top Tier PR Media Exposure of Your Company for 
                   Free.</strong><br/> 
                  <span className="text-muted">{ exp[2] } • Los Angeles and Ottawa Canada</span><br /> 
                  <span className="description">{ exp[1] }</span> 

                 </div> 
                </div> 
                <div className="col-lg-3"> 
                 <span className="price"> 
                  <div className="input-group"> 
                   <span className="input-group-addon" id="basic-addon1">$5/min</span> 
                   <input type="button" className="form-control btn-success" value="Request a call" placeholder="Username" aria-describedby="basic-addon1"/> 
                  </div> 
                 </span> 
                </div> 
               </div> 
               <div className="col-lg-12"> 
                <hr className="step-divider"/> 
               </div> 
              </div> 
             ) 
            }) 

            } 
           </Tab> 
           <Tab eventKey={3} title="Popular" className="tab-ind"> 
            <div className="col-lg-12"> 
             <div className="col-lg-2"> 
              <div className="well"> 
               <img className="img-responsive" alt="alt-messagex" 
                src="http://placehold.it/350x150"/> 
              </div> 
             </div> 
             <div className="col-lg-7"> 
              <div className="well"> 
               <strong>Get Top Tier PR Media Exposure of Your Company for 
                Free.</strong><br/> 
               <span className="text-muted">Ardian Salamunovlo • Los Angeles and Ottawa Canada</span><br /> 
               <span className="description">I will show you how to get you top-tier media exposure. Wether you want to be featured, in TechCrunch or Mashable, WSJ, or Forbes, Inc. or FastCompany I've done it dozens of times and I have the experience to...</span> 

              </div> 
             </div> 
             <div className="col-lg-3"> 
              <span className="price"> 
               <div className="input-group"> 
                <span className="input-group-addon" id="basic-addon1">$5/min</span> 
               <input type="button" className="form-control btn-success" 
                 value="Request a call" placeholder="Username" 
                 aria-describedby="basic-addon1"/> 
               </div> 
              </span> 
             </div> 
            </div> 
            <div className="col-lg-12"> 
             <hr className="step-divider"/> 
            </div> 
            <div className="col-lg-12"> 
             <div className="col-lg-2"> 
              <div className="well"> 
               <img className="img-responsive" alt="alt-message4" 
                src="http://placehold.it/350x150"/> 
              </div> 
             </div> 
             <div className="col-lg-7"> 
              <div className="well"> 
               <strong>Get Top Tier PR Media Exposure of Your Company for 
                Free.</strong><br/> 
               <span className="text-muted">Ardian Salamunovlo • Los Angeles and Ottawa Canada</span><br /> 
               <span className="description">I will show you how to get you top-tier media exposure. Wether you want to be featured, in TechCrunch or Mashable, WSJ, or Forbes, Inc. or FastCompany I've done it dozens of times and I have the experience to...</span> 

              </div> 
             </div> 
             <div className="col-lg-3"> 
              <span className="price"> 
               <div className="input-group"> 
                <span className="input-group-addon" id="basic-addon1">$5/min</span> 
               <input type="button" className="form-control btn-success" 
                 value="Request a call" placeholder="Username" 
                 aria-describedby="basic-addon1"/> 
               </div> 
              </span> 
             </div> 
            </div> 
           </Tab> 
          </Tabs> 
         </div> 
        </div> 

       </div> 
      </div> 
     ); 
    } 
} 

export default App; 

render()方法中的代碼可能沒有什麼意義,因爲它,我還在調試。

另外,我需要知道合適的地方打電話refineFeatured()refineNew()方法,我不能叫他們constructor()方法的組件沒有在這一點上還沒有初始化。

出於某種原因,當我用componenetDidMount()方法調用它們時,它們似乎不起作用。

任何幫助將不勝感激。

回答

0

調用setState()並不能保證你的狀態更新immdiatelety,看到反應文檔:

的setState()不會立即發生變異this.state而是創建一個 掛起狀態轉變。調用 方法後訪問this.state可能會返回現有值。 1

這意味着你仍然在訪問一個空的數組。您可以通過將allExperts數組傳遞給您的refineFeatured函數來解決此問題,而不是通過this.state傳遞它。