我是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状态数组。
答案 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()
中的数组呈现出来,因为该值将被呈现,这将帮助您理解问题。