【问题标题】:React Firebase read data results in too many rendersReact Firebase 读取数据导致渲染过多
【发布时间】:2022-02-07 12:48:50
【问题描述】:

我正在为我的 react 项目使用 Firebase 实时数据库。我尝试遵循 firebase 文档并使用“onValue()”来检索数据。这是我的代码:

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>
    )
}

这会导致重新渲染过多的错误。我不知道如何检索数据。如果我使用

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

然后正确的数据将在控制台中完美地打印出来。我还尝试了以下方法:

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

但信息只是未定义。我似乎无法弄清楚这里的问题。我如何使用这些数据?

【问题讨论】:

    标签: reactjs firebase-realtime-database


    【解决方案1】:

    它会引发错误太多重新渲染,因为您没有使用任何生命周期挂钩或函数来更新/更改状态值,一旦您更新状态,它将再次重新渲染您的整个组件,然后您再次更新状态和循环中发生了同样的事情,导致重新渲染过多。
    因此,为避免这种情况,您需要将负责侦听来自 DB 的更改和更改状态的代码放在一个块内,该块只会在特定事件或函数调用等时被调用。

    在你的情况下,我建议使用useEffect 钩子。见下面的代码 -

    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>
        )
    }
    

    注意 - 我最近没有使用 firebase 实时数据库,但是通过查看代码和错误,我添加了这个答案,如果有什么需要更正,请告诉我。

    【讨论】:

    • 用户 uid 应该传递给 useEffect 显示 userEffect 只会在用户 uid 更改时运行。
    • 是的,我猜应该将uid添加到useEffect中的依赖数组中。
    猜你喜欢
    • 2020-01-07
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多