I'm making a facebook clone, on my home Feed, I want to show all posts, this code shows posts but not in order, want to show the latest post first.
but now this is showing (old post (which were already loaded) in descending order and after that all new post in correct order )
import React ,{useState,useEffect} from 'react'
import './stylesheets/HomeFeed.css';
import HomeReels from './HomeReels'
import CreatePost from './CreatePost';
import Post from './Post';
import { ref, onValue} from "firebase/database";
import { realtimedb } from '../firebaseConfiguration';
export default function HomeFeed() {
const [postdata, setpostdata] = useState([])
const starCountRef = ref(realtimedb, 'Posts/');
// get post from realtime database
useEffect(()=>{
onValue(starCountRef, async (snapshot) => {
const data = snapshot.val();
var captions=[];
//data is stored in raltime db firebase as ----> Post > uid > timestamp >{caption:"captions"}
// conver objects to array , to store strings in final array data structure is in realtimedb > post > {uid:{time:{caption:"caption}}}
(Object.values(data)).forEach((e)=>{
(Object.values(e)).forEach((p)=>{
captions.unshift(p.caption)
})
});
setpostdata(captions)
});
},[])
// make Post components
const postRender = postdata.map((e)=>{
return<>
<Post caption={e}/>
</>
})
return (
<div className='HomeFeed'>
<HomeReels />
<CreatePost />
{postRender}
</div>
)
}
uses caption as post data and receive it as props
This commented out line is actually how you're supposed to do this:
// const [postdatabeforeload, setpostdatabeforeload] = useState([])
Without useState or setState your rendering code runs before the data is loaded from the database, so it renders the empty array you set initially: var postdata=[].
By using useState/setState you tell ReactJS that the data has changed, and that triggers it to rerender the UI with the updated state.
So something like:
const [postdata, setpostdata] = useState([])
const starCountRef = ref(realtimedb, 'Posts/');
useEffect(() => {
onValue(starCountRef, async (snapshot) => {
const captions = [];
snapshot.forEach((child) => {
captions.push(child.val().caption);
});
setpostdata(data)
});
}, [])
Until the useEffect has execute, your postdata will have its default value of [], as that's what you specify here [postdata, setpostdata] = useState([]).
Then once the data has loaded, you'll get the array of captions.
Also see: