ReactJS状态被重置

时间:2016-11-15 01:09:49

标签: javascript reactjs

我有以下firebase数据库:

enter image description here

我想要一个通过数据库的反应脚本,并按位置表征数据。这是我的尝试。

我创建了以下几种状态:

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


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

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

然后我创建了以下方法来填充allExperts状态:

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();
    }

我认为这将填充allExperts与数据库中的任何内容。 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()中的allExperts。

以下是整个代码:

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()方法打电话时,他们似乎无法工作。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

调用setState()并不能保证你的状态更新为immdiatelety,请参阅反应文档:

  

setState()不会立即改变this.state但会创建一个   待定状态转换。调用后访问this.state   方法可以返回现有值。 1

这意味着您仍在访问旧数组,这是一个空数组。您可以通过将allExperts数组传递给refineFeatured函数来解决此问题,而不是通过this.state传递它。