问题描述
我的问题很简单.我有一个 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:
- 自动确保每个 UID 只能存在一次,因为根据定义,键在节点中是唯一的.
- 无需查询即可使用给定的 UID 加载用户,如果您接触到数十万用户,则可以更好地扩展.
- 不再需要在回调中循环.
所以在这种情况下,加载用户/名称变为:
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 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!