打开数组时 Firebase undefined 不是对象
所以这真的很奇怪
这是我的代码,当它工作时
useEffect(() => {
// Alleen preview
async function getTracksData() {
let TrackData = await firebase
.firestore()
.collection('TrackScreen')
.doc('LeerjarenData')
.get();
if (!TrackData.exists) {
console.log('Geen data')
} else {
let TrackDatav2 = TrackData.data();
setTrackScreenData(TrackDatav2)
}
} getTracksData()
// SNAPSHOT USER DATA
db.collection("users").doc(currentUserUID)
.onSnapshot((doc) => {
setUserData(doc.data());
});
}, [])
console.log(trackscreenData.data)
这工作得很好,但是当我将我的控制台更改为
console.log(trackscreenData.data[0]
它给了我这个错误
TypeError: undefined is not an object (evaluating 'trackscreenData.data[0]')
然后当我再次将我的控制台更改为
console.log(trackscreenData.data)
它可以工作,当我更改回
console.log(trackscreenData.data[0])
并保存更改时它会给我我想要的数据
我做错了什么?
简而言之,您试图在异步调用中尚未准备好数据时使用它。
要处理数据尚未完成加载的情况,您应该使用:
console.log(trackscreenData && trackscreenData.data)
根据代码中的模式,您在组件顶部有这些行。
const { currentUserID } = useAuth(); // or similar
const [userData, setUserData] = useState();
const [trackscreenData, setTrackScreenData] = useState();
// NOTE: check for typos: "trackscreenData" !== "trackScreenData"
在代码
首次渲染
时,
trackscreenData
将为
未定义
,因为您尚未将初始状态传递到
useState()
方法中。
const [trackscreenData, setTrackScreenData] = useState(/* initial state */);
// `trackscreenData` initially set to `null`
const [trackscreenData, getTracksData] = useState(null);
// `trackscreenData` initially set to `[]`
const [trackscreenData, getTracksData] = useState([]);
// `trackscreenData` initially set to the result of the function,
// an array containing the elements 0 through 99. The function is
// only executed once to set the first value.
// trackscreenData = [0, 1, 2, 3, ... , 97, 98, 99];
const [trackscreenData, getTracksData] = useState(() => {
Array.from({length: 100})
.map((_, i) => i);
}
当 React 执行您的代码时,任何从
useState
调用(例如
setTrackScreenData
)返回的 setter 调用都会
排队
。仅当您的代码执行完毕后,才会对它们进行评估并触发任何新的渲染。
const [count, setCount] = useState(0); // `count` is initially set to `0`
useEffect(() => {
if (count < 10) {
setCount(count + 1);
}
})
console.log(count);
console.log("rendered");
// Console logs:
// > "0"
// > "rendered"
// > "1"
// > "rendered"
// > ...
// > "9"
// > "rendered"
// > "10"
// > "rendered"
您对用户数据的提取应在其自己的
useEffect
调用中进行,并应返回其取消订阅函数:
useEffect(() => {
if (!currentUserUID) {
setUserData(null); // user not signed in
return;
}
// SNAPSHOT USER DATA
return db.collection("users") // <- note the return here
.doc(currentUserUID)
.onSnapshot((doc) => {
setUserData(doc.data());
});
}, [currentUserUID]);
useEffect(() => {
let disposed = false;
// Alleen preview
async function getTracksData() {
let TrackData = await firebase
.firestore()
.collection('TrackScreen')
.doc('LeerjarenData')
.get();
if (disposed) return; // component was removed, do nothing
if (!TrackData.exists) {
console.log('Geen data')
} else {
let TrackDatav2 = TrackData.data();
setTrackScreenData(TrackDatav2)
}
}
getTracksData()
.catch((err) => console.error(err)); // don't forget to handle errors!
return () => disposed = true; // ignore result if component disposed
}, []);
您通过
.doc(...)
指定文档 ID,因此您将获得
DataSnapshot
作为响应,它不是数组。
如果您使用类似
.where(...)
的查询,那么它将返回
QuerySnapshot
。
A QuerySnapshot contains zero or more DocumentSnapshot objects representing the results of a query. The documents can be accessed as an array via the docs property or enumerated using the forEach method. The number of documents can be determined via the empty and size properties.
因此,如果您仅通过这种方式获取单个文档,则无需通过
[0]
访问文档,因为它不是数组。您可以简单地通过
dataSnapshot.data()
访问数据。
虽然我看不到
trackscreenData
在哪里定义?
useEffect(() => {
// Alleen preview
async function getTracksData() {
let TrackData = await firebase
.firestore()
.collection('TrackScreen')
.doc('LeerjarenData')
.get();
if (!TrackData.exists) {
console.log('Geen data')
} else {
let TrackDatav2 = TrackData.data();
setTrackScreenData(TrackDatav2)
console.log(trackScreenData)
}
}
}, [])