Javascript componentDidMount最初不呈现我的数据,仅在componentDidUpdate上呈现

Javascript componentDidMount最初不呈现我的数据,仅在componentDidUpdate上呈现,javascript,reactjs,firebase,firebase-realtime-database,Javascript,Reactjs,Firebase,Firebase Realtime Database,我是新手,我相信可能有一种更简单的方法来做这件事,但我正在尝试加载属于特定组的所有事件,该组的ID作为道具传递给事件组件。每次使用componentDidUpdate和getDerivedStateFromProps选择新组时,事件都会发生更改。该功能可以工作,但我遇到的问题是,在componentDidMount上,我被呈现为一个空的事件数组,因此在组的第一次单击时没有显示任何内容,但在第二次单击时(以及之后)会显示这些内容 以下是事件组件: import React, { Component

我是新手,我相信可能有一种更简单的方法来做这件事,但我正在尝试加载属于特定组的所有事件,该组的ID作为道具传递给事件组件。每次使用componentDidUpdate和getDerivedStateFromProps选择新组时,事件都会发生更改。该功能可以工作,但我遇到的问题是,在componentDidMount上,我被呈现为一个空的事件数组,因此在组的第一次单击时没有显示任何内容,但在第二次单击时(以及之后)会显示这些内容

以下是事件组件:

import React, { Component } from 'react';
import { Card, CardActionArea, CardMedia, CardContent, Typography, 
CardActions, Button, Grid } from '@material-ui/core';
import firebase from '../config/Fire'; 

export class Events extends Component {
constructor(props){
    super(props);
    this.state = {
        currentGroup: '',
        eventHold: [],
        loaded: false
    }
    this.formatDate = this.formatDate.bind(this);
    this.loadEvents = this.loadEvents.bind(this);
}
componentDidMount(){
    this.setState({currentGroup: this.props.currentGroup}, () => {this.loadEvents(this.state.currentGroup)})
}

componentDidUpdate(prevProps, prevState){
    if(prevState.currentGroup !== this.state.currentGroup){
        const newGroup = this.state.currentGroup;
        this.setState({currentGroup: newGroup}, () => {
            this.loadEvents(newGroup);
        });
    }
}
static getDerivedStateFromProps(nextProps, prevState){
    if(nextProps.currentGroup!==prevState.currentGroup){
        return {currentGroup : nextProps.currentGroup};
    }
    else
        return null;
}
loadEvents(groupid){
    const groupRef = firebase.database().ref('groups').child(groupid).child('events');
    var tempIdHold =[];
    groupRef.on('value', snapshot => {
        snapshot.forEach(snap => {
            tempIdHold.push(snap.key)
        })
    })
    const rootRef = firebase.database().ref('events');
    const tempEventHold =[];
    tempIdHold.forEach(event => { 
        rootRef.child(event).on('value', snap => {
            let newEvent = {
                id: snap.key,
                title: snap.val().title,
                description: snap.val().description,
                date: snap.val().date
            };
            tempEventHold.push(newEvent);
        })
    }); 
    this.setState({
        eventHold: tempEventHold,
        loaded:true
    })
}
formatDate = ( date ) => {
    const year = date.substring(0,4);
    const month = date.substring(5,7);
    const day = date.substring(8,10);
    const dateObj = new Date(year, month-1, day);

    return dateObj.toLocaleDateString();
}
render(){
    console.log(this.state.loaded);
    if(this.state.loaded){
        return(
            <div>
                <Grid container 
                    spacing={24} 
                    justify="center"
                    alignItems="center">
                {this.state.eventHold.map(event => 
                    <Grid item key={event.id}>
                        <Card>
                            <CardActionArea>
                            <CardMedia
                                component="img"
                                alt=""
                                height="140"
                                image= "blank"
                                title=""
                            />
                            <CardContent>
                                <Typography gutterBottom variant="h5" component="h2">
                                {event.title}
                                </Typography>
                                <Typography component="p">
                                {this.formatDate(event.date)}
                                </Typography>
                                <Typography component="p">
                                {event.id}
                                </Typography>
                                <Typography component="p">
                                {this.state.currentGroup}
                                </Typography>
                            </CardContent>
                            </CardActionArea>
                            <CardActions>
                            <Button size="small" color="primary">
                                Like
                            </Button>
                            <Button size="small" color="primary">
                                Comment
                            </Button>
                            <Button size="small" color="primary">
                                Learn More
                            </Button>
                            </CardActions>
                        </Card>
                    </Grid>
                )}
                </Grid>
            </div>
        )
    }
    return (
        <div>
            <img src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif" />
        </div>
      )
}
import React,{Component}来自'React';
导入{卡片、CardActionArea、CardMedia、CardContent、排版、,
来自“@material ui/core”的CardActions,Button,Grid};
从“../config/Fire”导入firebase;
导出类事件扩展组件{
建造师(道具){
超级(道具);
此.state={
当前组:“”,
事件保持:[],
加载:false
}
this.formatDate=this.formatDate.bind(this);
this.loadEvents=this.loadEvents.bind(this);
}
componentDidMount(){
this.setState({currentGroup:this.props.currentGroup},()=>{this.loadEvents(this.state.currentGroup)})
}
componentDidUpdate(prevProps、prevState){
if(prevState.currentGroup!==this.state.currentGroup){
const newGroup=this.state.currentGroup;
this.setState({currentGroup:newGroup},()=>{
这是loadEvents(newGroup);
});
}
}
静态getDerivedStateFromProps(下一步,上一步){
if(nextrops.currentGroup!==prevState.currentGroup){
返回{currentGroup:nextrops.currentGroup};
}
其他的
返回null;
}
loadEvents(groupid){
const groupRef=firebase.database().ref('groups').child(groupid).child('events');
var tempIdHold=[];
groupRef.on('value',快照=>{
snapshot.forEach(snap=>{
tempIdHold.push(捕捉键)
})
})
const rootRef=firebase.database().ref('events');
常量tempEventHold=[];
tempIdHold.forEach(事件=>{
rootRef.child(事件).on('value',snap=>{
让newEvent={
id:snap.key,
标题:snap.val().title,
description:snap.val().description,
日期:snap.val().date
};
tempEventHold.push(newEvent);
})
}); 
这是我的国家({
eventHold:tempEventHold,
加载:正确
})
}
formatDate=(日期)=>{
const year=日期子字符串(0,4);
const month=日期子串(5,7);
const day=日期子串(8,10);
const dateObj=新日期(年、月1日);
return dateObj.toLocaleDateString();
}
render(){
console.log(this.state.loaded);
if(this.state.loaded){
返回(
{this.state.eventHold.map(事件=>
{event.title}
{this.formatDate(event.date)}
{event.id}
{this.state.currentGroup}
喜欢
评论
了解更多
)}
)
}
返回(
)
}
}

loadEvents()的快速解释:我正在从“groups”Firebase节点下的currentGroup(应在屏幕上呈现的组)检索所有EventID,并将其保存到临时数组中,我在该数组中迭代以从“events”检索事件数据Firebase节点并推送到临时事件数组,然后将临时事件数组推送到eventHold状态数组

“setState()并不总是立即更新组件。它可能会批处理更新或将更新延迟到以后。”

ComponentDidMount()


您必须在
render()
方法中
console.log()
您的数组,因为setState并不总是按时更改状态(这行代码),而是在调用
render()
之前将所有
setState()
调用和更新排队
console.log()
render()
中呈现您的数组,因为该值将被呈现,它将帮助您了解问题。

是否需要
currentGroup
处于状态?为什么不直接从道具中引用呢?然后在
componentDidMount
中调用
this.loadEvents()
并在
componentDidUpdate
中将
prevProps
this.props
进行比较。另外,我不确定您是否需要
getDerivedStateFromProps
。最好在
componentDidMount
setState({currentGroup:this.props.currentGroup}
,而不是在
this.state
中设置它,因为通过react和设置两次来比较状态是没有用的,也不会
re Render()
组件。渲染显示了同样的问题,这是有意义的,我在第一次单击时有一个空数组,但在第二次单击时有一个填充数组。是否有方法将数组预加载到组件?我知道compo