我正在尝试从Firestore加载数据并将其显示在甘特图中,但是它是在从Firebase加载数据之前进行渲染的。因此,我在componentDidMount内部调用setState,因为我认为这将再次调用渲染器,此时数据将在那里。但是它仍然空着。有什么想法吗?
import React, { Component } from 'react';
import Gantt from './Gantt';
import Toolbar from './Toolbar';
import MessageArea from './MessageArea';
import Firebase from './Firebase';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
currentZoom: 'Days',
messages: [],
projects: [],
links: []
};
this.handleZoomChange = this.handleZoomChange.bind(this);
this.logTaskUpdate = this.logTaskUpdate.bind(this);
this.logLinkUpdate = this.logLinkUpdate.bind(this);
}
componentDidMount() {
const db = Firebase.firestore();
var projectsArr = [];
db.collection('projects').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
let project = doc.data();
projectsArr.push({id: 1, text: project.name, start_date: '15-04-2017', duration: 3, progress: 0.6});
});
});
this.setState({
projects: projectsArr
});
}
addMessage(message) {
var messages = this.state.messages.slice();
var prevKey = messages.length ? messages[0].key: 0;
messages.unshift({key: prevKey + 1, message});
if(messages.length > 40){
messages.pop();
}
this.setState({messages});
}
logTaskUpdate(id, mode, task) {
let text = task && task.text ? ` (${task.text})`: '';
let message = `Task ${mode}: ${id} ${text}`;
this.addMessage(message);
}
logLinkUpdate(id, mode, link) {
let message = `Link ${mode}: ${id}`;
if (link) {
message += ` ( source: ${link.source}, target: ${link.target} )`;
}
this.addMessage(message)
}
handleZoomChange(zoom) {
this.setState({
currentZoom: zoom
});
}
render() {
var projectData = {data: this.state.projects, links: this.state.links};
return (
<div>
<Toolbar
zoom={this.state.currentZoom}
onZoomChange={this.handleZoomChange}
/>
<div className="gantt-container">
<Gantt
tasks={projectData}
zoom={this.state.currentZoom}
onTaskUpdated={this.logTaskUpdate}
onLinkUpdated={this.logLinkUpdate}
/>
</div>
<MessageArea
messages={this.state.messages}
/>
</div>
);
}
}
export default App;
答案 0 :(得分:1)
您正在setState
回调之外调用then
。
所以改变
db.collection('projects').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
let project = doc.data();
projectsArr.push({id: 1, text: project.name, start_date: '15-04-2017', duration: 3, progress: 0.6});
});
});
this.setState({
projects: projectsArr
});
收件人
db.collection('projects').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
let project = doc.data();
projectsArr.push({id: 1, text: project.name, start_date: '15-04-2017', duration: 3, progress: 0.6});
});
this.setState({
projects: projectsArr
});
});
此外,作为一般模式,您可以执行以下操作:
class AsyncLoad extends React.Component {
state = { data: null }
componentDidMount () {
setTimeout(() => {
this.setState({ data: [1, 2, 3]})
}, 3000)
}
render () {
const { data } = this.state
if (!data) { return <div>Loading...</div> }
return (
<pre>{JSON.stringify(data, null, 4)}</pre>
)
}
}
这是为它创建HOC的足够常见的操作。