componentDidMount最初仅在componentDidUpdate

时间:2018-10-23 20:32:25

标签: javascript reactjs firebase firebase-realtime-database

我是React的新手,我敢肯定有一种更简单的方法可以做到这一点,但是我正在尝试加载属于特定组的所有事件,这些ID的ID作为道具传递给了Events组件。每当使用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>
      )
}

}

loadEvents()的简要说明:我从“组” Firebase节点下的currentGroup(应在屏幕上呈现的组)中检索所有eventID,并将其保存到临时数组中,以进行迭代以检索来自“事件” Firebase节点的事件数据,并推送到临时事件数组,然后将其推送到eventHold状态数组。

1 个答案:

答案 0 :(得分:1)

  

“ setState()并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。” ,React docs setState()

int a = 1; int b = 2; return " "+a+b; 仅在return String.valueOf(int1)+String.valueOf(int2); 之后运行一次,而ComponentDidMount()在每次更新状态后运行。 State and LifeCycle

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