反应应用渲染公司的FireStore数据加载之前

问题描述 投票:1回答:1

我试图从公司的FireStore加载数据并显示在甘特图表中,但它使得它从火力加载数据之前。于是我打电话的setState componentDidMount里面,因为我以为那么这将再次调用呈现在该点的数据会在那里。但它仍然空置。任何想法,为什么?

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;
reactjs firebase components render
1个回答
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它。

© www.soinside.com 2019 - 2024. All rights reserved.