我有以下firebase数据库:
我想要一个通过数据库的反应脚本,并按位置表征数据。这是我的尝试。
我创建了以下几种状态:
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()
方法打电话时,他们似乎无法工作。
非常感谢任何帮助。
答案 0 :(得分:0)
调用setState()
并不能保证你的状态更新为immdiatelety,请参阅反应文档:
setState()不会立即改变this.state但会创建一个 待定状态转换。调用后访问this.state 方法可以返回现有值。 1
这意味着您仍在访问旧数组,这是一个空数组。您可以通过将allExperts数组传递给refineFeatured函数来解决此问题,而不是通过this.state
传递它。