Reputation: 197
Anytime the list updates, it forms another array that adds to the previous array, how can I make it to return just one array with the updated information
below is the code
useEffect(() => {
firebase.database().ref('/users/' + '/messages/').orderByChild('createdAt').on('value', function(snapshot) {
snapshot.forEach(function(userSnapshot) {
const id = userSnapshot.key;
const userData = userSnapshot.val();
setId(id);
messages.push(userData);
});
});
setMessages(messages);
}, [messages])
usage in body
<ul>
{messages.map(function(item){
return (<li key={id}>{item.displayName}: {item.text}</li>)
})}
</ul>
when the list updates once, it returns two more lists, so the new list becomes very very long
Upvotes: 0
Views: 1123
Reputation: 388
If your messages is a state variable you should never ever change it directly, what you should do is something like
const newMessages = Array.from(messages);
snap.forEach(message => newMessages.push(message))
setMessages(newMessages);
But of course is the snap is containing ALL your messages then you can just initialize newMessages as an empty array
Upvotes: 1
Reputation: 598837
I think you're looking for:
firebase.database().ref('/users/' + '/messages/').orderByChild('createdAt').on('value', function(snapshot) {
messages = []; // clear existing messages
snapshot.forEach(function(userSnapshot) {
const id = userSnapshot.key;
const userData = userSnapshot.val();
setId(id);
messages.push(userData);
});
setMessages(messages);
});
The changes in here:
messages
array before adding the updated items to it.setMessages
inside the callback, to ensure it gets called when the latest data from the database is in messages
.Upvotes: 1