在React中从Firebase渲染数据

时间:2018-11-27 10:28:25

标签: javascript reactjs firebase firebase-realtime-database

请帮我渲染从Firebase实时数据库检索的数据。

我成功地从Firebase检索了数据作为数组。下一步是显示数据-问题就从这里开始。

我要显示的数据应该以“模块”状态存储。首先,将其设置为空数组。然后检索数据,使用CoumponentDidMount生命周期方法中的setState更新状态-我可以在React DevTool中将数据视为数组-但是组件未呈现(显示)它们。

我认为问题可能与生命周期方法有关,因为我可以在控制台中记录状态,但是我还可以看到一个弹出信息,表明该数组(从Firebase派生)“刚刚被评估”。 。如果我是对的,这意味着在render方法之后要检索数据吗?我该怎么办才能解决问题并正确播放数据?

这是我的代码:

    import React, { Component } from "react";
import firebase from "firebase";
import { DB_CONFIG } from "./database/db_config";
import ModulesData from "./modulesData";
//import LandingPage from "./components/landingPageComponents/landingPage";
import ThematicAreaNav from "./components/navbarComponents/thematicAreaNav";
import ThematicArea from "./components/singleModuleComponents/thematicArea";
import OrderList from "./components/orderListComponents/orderList";
import Footer from "./components/footerComponents/footer";

let chosenModulesArray = [];

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      holdClickedModulesNames: chosenModulesArray,
      modules: []
    };
  }

  componentDidMount() {
    let ref = firebase
      .initializeApp(DB_CONFIG)
      .database()
      .ref();

    ref.once("value").then(dataSnapshot => {
      this.response = dataSnapshot.val()["modulesData"];
      this.setState({ modules: this.response });
    });
  }

  render() {
    return (
      <div>
        {console.log(this.state.modules)}}{/*<LandingPage />*/}
        <ThematicAreaNav modules={this.state.modules} />
        <div className="main-layout">
          <ThematicArea
            modules={this.state.modules}
            orderedModules={this.props.orderedModules}
            clickedModuleNames={this.state.holdClickedModulesNames}
            chosenModulesNames={this.state.holdClickedModulesNames}
          />

          <OrderList
            clickedModuleNames={this.state.holdClickedModulesNames}
            chosenModulesNames={this.state.holdClickedModulesNames}
          />
        </div>
        <div className="footer">
          <Footer />
        </div>
      </div>
    );
  }
}

export default App;

enter code here

2 个答案:

答案 0 :(得分:1)

从视觉角度看 如果您的数据是在class app extends Component { constructor(props){ modules:null, loading:true, } componentDidMount(){ getModules(); } getModules(){ let ref = firebase .initializeApp(DB_CONFIG) .database() .ref(); ref.once("value").then(dataSnapshot => { this.response = dataSnapshot.val()["modulesData"]; //once the data is back, set the loading to false so it can be rendered this.setState({ data: this.response, loading: false }); }); } render(){ // deconstruct 'modules' from the state to call it without this.state... const {modules, loading, holdClickedModulesNames} = this.state; const { orderedModules } = this.props; return loading ? ( <div> loading... </div> ) : ( <div> <ThematicAreaNav modules={modules} /> <div className="main-layout"> <ThematicArea modules={modules} orderedModules={orderedModules} clickedModuleNames={holdClickedModulesNames} chosenModulesNames={holdClickedModulesNames} /> <OrderList clickedModuleNames={holdClickedModulesNames} chosenModulesNames={holdClickedModulesNames} /> </div> <div className="footer"> <Footer /> </div> </div> ) } } 之后返回的,而不是显示空白屏幕或填充一半的组件,请显示一个加载屏幕,等待填充数据-从UX角度来看,这始终是一种好习惯!

代码示例:

{{1}}

答案 1 :(得分:0)

Bcoz您正在尝试在componentDidMount()方法中执行异步操作。您可以使用异步等待:

async componentDidMount() {
    let ref = await firebase
      .initializeApp(DB_CONFIG)
      .database()
      .ref();

    const firebaseResponse = await ref.once("value");

    this.response = firebaseResponse.val()["modulesData"];
    this.setState({ modules: this.response });
}