所以这真的很奇怪
这是我的代码,当它工作时
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])并保存为我提供所需数据的更改
我做错了什么?
发布于 2021-06-26 15:55:41
简而言之,在异步调用数据准备就绪之前,您正在尝试使用这些数据。
要处理数据尚未完成加载的情况,您应该使用:
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将为undefined,因为您还没有将初始状态传递给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的调用都是queued。只有当您的代码执行完毕后,才会对它们进行评估并触发任何新的呈现。
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
}, []);发布于 2021-06-26 15:29:36
您正在通过.doc(...)指定文档ID,因此您将获得一个DataSnapshot作为响应,它不是一个数组。
如果你使用像.where(...)这样的查询,那么它将返回一个QuerySnapshot。
QuerySnapshot包含零个或多个表示查询结果的DocumentSnapshot对象。可以通过docs属性将文档作为数组访问,也可以使用forEach方法枚举文档。文档的数量可以通过empty和size属性确定。
因此,如果只以这种方式获取单个文档,则不需要通过[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)
}
}
}, [])https://stackoverflow.com/questions/68140057
复制相似问题