首页 > 解决方案 > 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。这就是我不明白的,为什么?

标签: reactjsfirebasereact-nativegoogle-cloud-firestorereact-hooks

解决方案


代码的行为应如此。您应该将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。这就是我不明白的,为什么?


推荐阅读