在 react useState 中使用时未定义 Firebase 数据 [英] Firebase data not defined when used inside react useState

查看:12
本文介绍了在 react useState 中使用时未定义 Firebase 数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题很简单.我有一个 firebase 实时数据库,我正在从数据库中获取数据并尝试插入到 useState 中,以便我可以在我的应用程序中显示这些数据.但无论我做什么,数据总是未定义或为空.奇怪的是,如果我在 jsx 组件中插入完全相同的数据或控制台记录它,它显示没有任何问题.

My issue is very simple. I have a firebase realtime database and i am fetching data from the database and trying to insert in inside a useState so that i can then display this data in my app. But no matter what i do, the data is always undefined or null. Strangely enough if i insert that same exact data inside a jsx component or console log it, it displays without any problem.

这是我正在做的事情以及问题的描述:

Here's what i am doing and a description of the problem:

首先是我的用户实时数据库

First here is my realtime-database with users

我只想访问 fullname 属性并将其插入到我的姓名"状态中

I simply want to access the fullname property and insert that inside my 'name' state

App.js

const userid = firebase.auth().currentUser.uid
const [usersList , setUsersList ] = useState([])
const [name, setName] = useState(usersList.fullname) //undefined

useEffect(() => {
const usersRef = firebase.database().ref('Users')
let query = usersRef.orderByChild('uid').equalTo(userid); 
query.on('value', (snapshot) => {
  const users = snapshot.val() 
  const usersList = []
  for (let id in users) {
    usersList.push({id, ...users[id]}) 
  }  
  setUsersList(usersList[0]) 
})
},[])

显示数据:

console.log(usersList.fullname) //displays my name perfectly well

return (
<div>{usersList.fullname}</div>
)

显示效果也很好

但是

const [name, setName] = useState(usersList.fullname) //undefined

这在我看来完全不合逻辑!如果您对发生这种情况的原因有任何见解,请与我分享.

This seems completely illogical to me! If yo have any insight on why this is happening, share it with me please.

推荐答案

您看到的是预期的行为.从 Firebase 加载数据(就像调用大多数云 API)是一个异步操作.这就是为什么你要传递一个函数 (snapshot) =>{...} 进入操作,以便在操作完成后回调您.

What you're seeing is the expected behavior. Loading data from Firebase (just like calling most cloud APIs) is an asynchronous operation. That's why you're passing a function (snapshot) => {...} into the operation, so that it can call you back when the operation has completed.

在此之前,该函数内的任何代码都没有运行,因此 usersList 将具有其默认值.由于您将状态初始化为 useState([]),它的默认值是 [],它没有 fullname 成员.

Until that happens, none of the code inside that function has run, so usersList will have its default value. And since you initialize the state as useState([]) its default value is [], which doesn't have a fullname member.

我猜你想在设置 usersList 后也设置用户名.所以:

My best guess it that you want to set the username too after setting usersList. So:

setUsersList(usersList[0]);
setName(usersList[0].fullname);


无关:将用户存储在其 UID 下更为惯用., 而不是像现在那样使用 push() .通过使用 UID 作为密钥,您:


Unrelated: it is more idiomatic to store the users under their UID. , instead of with push() as you do now. By using the UID as the key, you:

  1. 自动确保每个 UID 只能存在一次,因为根据定义,键在节点中是唯一的.
  2. 无需查询即可使用给定的 UID 加载用户,如果您接触到数十万用户,则可以更好地扩展.
  3. 不再需要在回调中循环.

所以在这种情况下,加载用户/名称变为:

So in that case, loading the user/name becomes:

useEffect(() => {
  const usersRef = firebase.database().ref('Users')
  let query = usersRef.child(userid); 
  query.on('value', (snapshot) => {
    const user = snapshot.val() 
    setUsersList(user);
    setName(user.fullname);
  })
},[])

这篇关于在 react useState 中使用时未定义 Firebase 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆