[英]React Native firebase function doesn't fetch correctly under useEffect
I am using react native and firebase firestore on a project.我在一个项目中使用 react native 和 firebase firestore 。
I want to fetch some data of the post in the post screen, and when I try to fetch it, it doesn't work from the first try.我想在帖子屏幕中获取帖子的一些数据,当我尝试获取它时,它从第一次尝试就不起作用。 I'm using useEffect to avoid infinite loops and I added a console.log to see what really happens.
我正在使用 useEffect 来避免无限循环,并添加了一个 console.log 来查看实际发生的情况。
What should happen: the firebase.firestore()...get() should retrieve the data of the post from firestore in an object inside an array.应该发生什么: firebase.firestore()...get() 应该从数组内的对象中的 firestore 检索帖子的数据。 However, when using useEffect, the first time it's unsuccessful.
但是,在使用useEffect的时候,第一次是不成功的。 I set a console.log after the whole fetch to check if the arr.length !== 0 and I can clearly see that arr.length === 0.
我在整个 fetch 之后设置了一个 console.log 来检查 arr.length !== 0 并且我可以清楚地看到 arr.length === 0。
However, here is the weird thing, If I let the useEffect run indefinitely, from the 2nd try on it retrieves the data good.然而,这是奇怪的事情,如果我让 useEffect 无限期地运行,从第二次尝试它就可以很好地检索数据。 Any ideas on how things can be solved?
关于如何解决问题的任何想法?
const [post, setPost] = useState([]);
useEffect(() => {
firebase.firestore()
.collection("allPosts")
.where(firebase.firestore.FieldPath.documentId(), '==', props.route.params.postId)
.get()
.then((snapshot) => {
let data = snapshot.docs.map(doc => {
const data = doc.data();
const id = doc.id;
return { id, ...data }
})
setPost(data)
})
if (post.length !== 0) {
console.log('Worked')
} else {
console.log('Empty')
}
}, [])
EDIT: const [post, setPost] = useState(null);编辑:const [post, setPost] = useState(null);
useEffect(() => {
// 1
firebase.firestore()
.collection("allPosts")
.where(firebase.firestore.FieldPath.documentId(), '==', props.route.params.postId)
.get()
.then((snapshot) => {
//2
let data = snapshot.docs.map(doc => {
const data = doc.data();
const id = doc.id;
return { id, ...data }
})
setPost(data)
//3
if (data.length !== 0) {
console.log('Worked')
} else {
console.log('Empty')
}
console.log(post)
})
}, [])
The console log of data.length returns worked, the console log of post(last) returns null. data.length 的控制台日志返回工作,post(last) 的控制台日志返回空。 That's what I don't understand, why?
这是我不明白的,为什么?
The code is behaving as it should.代码行为正常。 You should move the
console.log
into the then
.您应该将
console.log
移动到then
。 The wait it's now it will be executed in this order:现在的等待将按以下顺序执行:
const [post, setPost] = useState([]);
useEffect(() => {
// 1
firebase.firestore()
.collection("allPosts")
.where(firebase.firestore.FieldPath.documentId(), '==', props.route.params.postId)
.get()
.then((snapshot) => {
//3
let data = snapshot.docs.map(doc => {
const data = doc.data();
const id = doc.id;
return {
id,
...data
}
})
setPost(data)
})
//2
if (post.length !== 0) {
console.log('Worked')
} else {
console.log('Empty')
}
}, [])
That is the reason you don't see any that in the first try.这就是您在第一次尝试中看不到任何内容的原因。 The
console.log
is executed before the async data is loaded from firestore.在从 firestore 加载异步数据之前执行
console.log
。
Change your code to this to make it work as expected:将您的代码更改为此以使其按预期工作:
const [post, setPost] = useState([]);
useEffect(() => {
// 1
firebase.firestore()
.collection("allPosts")
.where(firebase.firestore.FieldPath.documentId(), '==', props.route.params.postId)
.get()
.then((snapshot) => {
//2
let data = snapshot.docs.map(doc => {
const data = doc.data();
const id = doc.id;
return {
id,
...data
}
})
setPost(data)
//3
if (data.length !== 0) {
console.log('Worked')
} else {
console.log('Empty')
}
})
}, [])
You could also use another useEffect
to log the changed data:您还可以使用另一个
useEffect
来记录更改的数据:
useEffect(()=>{
if (post.length !== 0) {
console.log('Worked')
} else {
console.log('Empty')
}
},[post])
Or just log it directly in the render function.或者直接在渲染函数中记录它。
EDIT:编辑:
const [post, setPost] = useState(null);
useEffect(() => {
// 1
firebase.firestore()
.collection("allPosts")
.where(firebase.firestore.FieldPath.documentId(), '==', props.route.params.postId)
.get()
.then((snapshot) => {
//2
let data = snapshot.docs.map(doc => {
const data = doc.data();
const id = doc.id;
return {
id,
...data
}
})
setPost(data)
//3
if (data.length !== 0) {
console.log('Worked')
} else {
console.log('Empty')
}
console.log(post)
})
}, [])
The console log of data.length returns worked, the console log of post(last) returns null. data.length 的控制台日志返回工作,post(last) 的控制台日志返回空。 That's what I don't understand, why?
这是我不明白的,为什么?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.