Javascript 在React中呈现Firebase中的数据

Javascript 在React中呈现Firebase中的数据,javascript,reactjs,firebase,firebase-realtime-database,Javascript,Reactjs,Firebase,Firebase Realtime Database,请帮助我渲染从Firebase实时数据库检索的数据 我成功地从Firebase中检索数据作为数组。下一步是显示数据——问题开始了 我想显示的数据应该以模块状态存储。首先,它被设置为一个空数组。然后检索数据,通过CouComponentDidMount生命周期方法中的setState更新状态-我可以在React DevTool中将数据视为数组-但组件未呈现并显示它们 我假设一个问题与生命周期方法有关,因为我可以在控制台中记录状态,但我也可以看到一个弹出信息,该信息是刚刚从Firebase检索到的阵

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

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

我想显示的数据应该以模块状态存储。首先,它被设置为一个空数组。然后检索数据,通过CouComponentDidMount生命周期方法中的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

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 });
}
从视觉角度看 如果在渲染后返回数据,而不是显示空白屏幕或半填充组件,则显示加载屏幕,而不是等待填充数据-从用户体验的角度来看,这始终是一种良好的做法

代码示例:

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

还是一模一样。我写了这样一篇文章:async componentDidMount{let ref=firebase.initializeAppDB_CONFIG.database.ref;const firebaseResponse=wait ref.oncevalue;wait ref.oncevalue.thendataSnapshot=>{this.response=dataSnapshot.val[modulesData];this.setState{modules:this.response};};}此方法是同步的还是异步的?如果是同步的,那么您还需要向其添加wait.None。更重要的是,我可以正确地记录从Firebase检索到的数据。所以这与配置无关。我甚至试着重新启动服务器。它包含一个对象数组-正是我需要显示的格式:并且说下面的值刚刚被评估过,非常感谢-非常棒!并感谢代码清理建议;另一方面,您可以创建一个组件,并在任何需要使用的时候导入它。为加载文本等传递道具。。。