post.on
является асинхронной c функцией, поэтому значение за пределами forEach l oop не определено для postArray
Решение здесь состоит в том, чтобы установить состояние внутри post.on. Это, однако, приведет к множественному setState, а также продолжит добавлять состояние данных postArray.
postsRef.on('value', function(snapshot) {
snapshot.forEach((subChild) => {
var value = subChild.val();
value = value.postID;
var post = firebase.database().ref('/posts/' + value);
post.on('value', function(snapshot2) {
postsArray = snapshot2.val();
setPosts(prevPosts => {
return [...prevPosts, ...Object.keys(postsArray).reverse().map(key => ({
key: key, ...postsArray[key]
}))];
})
});
})
})
Лучшим решением здесь является преобразование синтаксиса обратного вызова для использования обещания. Я не уверен, что firebase.database предоставляет формат обещания, поэтому я просто покажу вам традиционный способ использования Promise.all и нового Promise
postsRef.on('value', async function(snapshot) {
const promises = []
snapshot.forEach((subChild) => {
var value = subChild.val();
value = value.postID;
var post = firebase.database().ref('/posts/' + value);
promises.push(new Promise((res, rej) => {
post.on('value', function(snapshot2) {
res(snapshot2.val())
});
}));
})
const postArray = await Promise.all(promises);
setPosts(prevPosts => {
return [
...prevPosts,
...Object.keys(postsArray).reverse().map(key => ({
key: key, ...postsArray[key]
}))
];
})
})