Home > Blockchain >  React Firebase read data results in too many renders
React Firebase read data results in too many renders

Time:02-07

I'm using Firebase realtime database for my react project. I try to follow the firebase documentation and use "onValue()" to retrieve data. Here is my code:

export default function Home() {
    
    const {currentUser} = useAuth();
    const [userinfo,setUserinfo] = React.useState();

    const uid = currentUser.uid
    const db = getDatabase();

    onValue(ref(db,`users/${uid}`),snapshot=>{
        const data = snapshot.val();
        setUserinfo(data);
    })


    console.log(userinfo);
    
    return (
    <main id="home">
        <Hero />
    </main>
    )
}

This would result in an error of too many re-renders. I don't know how to retrieve the data. If I use

onValue(ref(db,`users/${uid}`),snapshot=>{
        const data = snapshot.val();
        console.log(data);
    })

then the proper data would print out in the console perfectly fine. I also tried the following:

let info;
onValue(ref(db,`users/${uid}`),snapshot=>{
        const data = snapshot.val();
        info = data;
    })
console.log(info)

but info would just be undefined. I can't seem to figure out the problem here. How can I use the data?

CodePudding user response:

It throws error too many re-renders because you are not using any lifecycle hook or function to update/change state value and once you update your state it will again re-render your whole component and then again you update the state and the same thing happens in the loop causing too many re-renders.
So to avoid this you need to put code that is responsible for listening to changes from DB and changing state inside a block which will only get called on specific events or function calls or etc.

In your case, I suggest using useEffect hook. see below code -

export default function Home() {

    const { currentUser } = useAuth();
    const [userinfo, setUserinfo] = React.useState();

    const uid = currentUser.uid
    const db = getDatabase();

    // this useEffect will get called only 
    // when component gets mounted first time
    useEffect(() => {
        // here onValue will get initialized once
        // and on db changes its callback will get invoked
        // resulting in changing your state value
        onValue(ref(db, `users/${uid}`), snapshot => {
            const data = snapshot.val();
            setUserinfo(data);
        })
        return () => {
            // this is cleanup function, will call just on component will unmount
            // you can clear your events listeners or any async calls here
        }
    }, [])

    console.log(userinfo);

    return (
        <main id="home">
            <Hero />
        </main>
    )
}

Note - I have not worked with firebase real-time DB recently but by looking at the code and error I have added this answer, let me know if anything needs correction.

  •  Tags:  
  • Related