Reactjs 关于在React中设置状态
下面是一个从firebase数据库获取消息的函数,但它仅将状态设置为一条消息 但是,Reactjs 关于在React中设置状态,reactjs,react-native,Reactjs,React Native,下面是一个从firebase数据库获取消息的函数,但它仅将状态设置为一条消息 但是,console.log可以在对象中记录多条消息。 我的功能有什么问题吗 getMessages(){ var messages = []; firebaseApp.database().ref('users/'+firebase.auth().currentUser.uid+'/userChat/'+firebase.auth().currentUser.uid).orderByValue().limitToLa
console.log
可以在对象中记录多条消息。
我的功能有什么问题吗
getMessages(){
var messages = [];
firebaseApp.database().ref('users/'+firebase.auth().currentUser.uid+'/userChat/'+firebase.auth().currentUser.uid).orderByValue().limitToLast(10).once('value', (dataSnapshot) => {
//alert(JSON.stringify(dataSnapshot.val()));
dataSnapshot.forEach((child) => {
firebaseApp.database().ref('messages').child(child.key).once("value", (message)=>{
//alert(JSON.stringify(messages));
messages.push({
_id: Math.round(Math.random() * 1000000),
text: message.val().text,
createdAt: new Date(message.val().timestamp),
user: {
_id: 1,
name: 'Developer',
},
});
this.setState({
messages: messages
});
console.log('woooo'+JSON.stringify(messages));
});
});
});
}
您正在forEach
块内设置状态。尝试将其移出迭代块
正如JanneKlouman提到的,在进行异步调用时,将其从iterration块中删除还不够好。
您可以创建一个新数组并将其设置为每次迭代时的状态,react将批处理这些设置状态调用:
function getMessages() {
var messages = [];
firebaseApp.database().ref('users/' + firebase.auth().currentUser.uid + '/userChat/' + firebase.auth().currentUser.uid).orderByValue().limitToLast(10).once('value', (dataSnapshot) => {
//alert(JSON.stringify(dataSnapshot.val()));
dataSnapshot.forEach((child) => {
firebaseApp.database().ref('messages').child(child.key).once("value", (message) => {
const newMessage = {
_id: Math.round(Math.random() * 1000000),
text: message.val().text,
createdAt: new Date(message.val().timestamp),
user: {
_id: 1,
name: 'Developer',
},
}
const nextState = this.state.messages.map(message => {
return {
...message,
user: {...meesage.user} // i think we must do this in order to break out of the reference as spreading will only work on a shallow level
}
});
this.setState({
messages: [...nextState, newMessage]
});
});
});
});
}
请在设置状态之前尝试克隆阵列:
getMessages(){
让消息=[];
firebaseApp.database().ref('users/'+firebase.auth().currentUser.uid+'/userChat/'+firebase.auth().currentUser.uid).orderByValue().limitToLast(10).once('value',(dataSnapshot)=>{
dataSnapshot.forEach((子项)=>{
firebaseApp.database().ref('messages').child(child.key).once('value',(message)=>{
常量消息={
_id:Math.round(Math.random()*1000000),
text:message.val().text,
createdAt:新日期(message.val().timestamp),
用户:{
_id:1,
名称:“开发者”,
},
};
//克隆消息
消息=[…消息,消息];
this.setState({messages});
});
});
});
}
这不等于this.setState({messages:[]})
,因为它是在firebase回调消息被激发之前运行的吗?@JanneKlouman看起来你是对的,它超出了第二个ref
范围。有没有办法先将所有消息保存在一个变量中,然后只设置一次state?spread
操作符只在一个层次深度上工作,这意味着meesage。用户会将对对象的引用保持在该状态。