componentDidMount не рендерит мои данные изначально, только на componentDidUpdate - PullRequest
0 голосов
/ 23 октября 2018

Я новичок в React, и я уверен, что, возможно, есть более простой способ сделать это, но я пытаюсь загрузить все события, которые принадлежат определенной группе, чей ID передается компонентам Events в качестве реквизита.События изменяются каждый раз, когда выбирается новая группа с использованием componentDidUpdate и getDerivedStateFromProps.Эта функциональность работает, но проблема, с которой я сталкиваюсь, заключается в том, что в componentDidMount я отображаю пустой массив событий, поэтому при первом щелчке группы ничего не отображается, а при втором (и).

Вот компонент Events:

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 (): я получаю все идентификаторы событий из currentGroup (группа, которая должна бытьотображается на экране) в узле Firebase "groups" и сохраняет их во временном массиве, который я перебираю, чтобы извлечь данные о событиях из узла Firebase "events" и переместить в массив временных событий, который затем передается в массив состояний eventHold.

1 Ответ

0 голосов
/ 24 октября 2018

"setState () не всегда немедленно обновляет компонент. Он может пакетировать или отложить обновление до более позднего периода.", React docs setState () .

ComponentDidMount() запускается только один раз после render(), тогда как ComponentDidUpdate() запускается после каждого обновления состояния. State и LifeCycle .

Вы должны console.log() свой массив в методе render(), так как setState не всегда меняет состояние вовремя (эта строка кода), вместо этого он ставит в очередь всеsetState() звонки и обновления непосредственно перед звонком render().console.log() ваш массив в render(), поскольку это значение будет отображено, это поможет вам понять проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...