reactjs - React Native firebase 函数在 useEffect 下无法正确获取
问题描述
我在一个项目中使用 react native 和 firebase firestore。
我想在帖子屏幕中获取帖子的一些数据,当我尝试获取它时,它从第一次尝试就不起作用。我正在使用 useEffect 来避免无限循环,并添加了一个 console.log 以查看实际发生的情况。
应该发生什么: firebase.firestore()...get() 应该从数组内的对象中的 firestore 检索帖子的数据。但是,在使用useEffect的时候,第一次是不成功的。我在整个提取后设置了一个 console.log 来检查 arr.length 是否为 !== 0,我可以清楚地看到 arr.length === 0。
然而,奇怪的是,如果我让 useEffect 无限期地运行,从第二次尝试它会很好地检索数据。关于如何解决问题的任何想法?
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')
}
}, [])
编辑: 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)
})
}, [])
data.length 的控制台日志返回工作,post(last) 的控制台日志返回 null。这就是我不明白的,为什么?
解决方案
代码的行为应如此。您应该将console.log
移入then
. 现在等待它将按以下顺序执行:
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')
}
}, [])
这就是您在第一次尝试时看不到任何内容的原因。在console.log
从 firestore 加载异步数据之前执行。
将您的代码更改为此以使其按预期工作:
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')
}
})
}, [])
您还可以使用另一个useEffect
来记录更改的数据:
useEffect(()=>{
if (post.length !== 0) {
console.log('Worked')
} else {
console.log('Empty')
}
},[post])
或者直接在渲染函数中记录。
编辑:
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)
})
}, [])
data.length 的控制台日志返回工作,post(last) 的控制台日志返回 null。这就是我不明白的,为什么?
推荐阅读
- magento2 - 用于保存配置 magento 2 的插件
- python - HTML页面图标未显示在Django中
- c - void 指针,并重新转换为所需的类型
- pine-script - pine 脚本 - ADX 指示修改
- reference - 防止 Visual Studio 2017 将近 100 个不必要的系统 dll 复制到 dll 项目的输出文件夹
- ios - 应用程序崩溃并调用 [ServicesDaemonManager] interruptHandler。-[FontServicesDaemonManager 连接]_block_invoke
- javascript - 如何使用 Selenium 和 Python 从由空格分隔的文本节点获取文本
- fonts - 无法嵌入字体时的位图文本
- javascript - .map() 显示来自 api 的数据的问题
- sql - 获取 oracle db 中的所有视图以及行数、列数、主键等详细信息