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