【问题标题】:React Native firebase function doesn't fetch correctly under useEffectReact Native firebase 函数在 useEffect 下无法正确获取
【发布时间】:2021-07-13 21:48:26
【问题描述】:

我在一个项目中使用 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。这就是我不明白的,为什么?

【问题讨论】:

    标签: reactjs firebase react-native google-cloud-firestore react-hooks


    【解决方案1】:

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

    【讨论】:

    • 你在第二个“好”代码中做了什么改变?
    • 我刚刚将 console.log 移到了then。听起来微不足道,但当您使用 async/await 时会产生巨大的差异
    • 显然这是来自 rn-firebase 的错误,它必须多次获取才能获取数据。与其他有此错误的人交谈。为我解决这个问题的奇怪之处是将 postState 用作 ([0]) 而不是 ([]) -> 非常奇怪。并且还使用 useEffect 和另一个状态来检查是否已加载并将该状态作为第二个参数传递给 useEffect
    • 我不想无礼。但是您的代码(来自问题)无法按预期工作。那是 100% 不是 Firebase 的错误。我不知道你问谁,但他们也应该多了解一点async/await。这甚至是一个与您的代码几乎相同的示例:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    • 用您的代码编辑了帖子。不过,最后一个 console.log 返回 null。 PS:我的错误,编辑了你的帖子而不是我的。抱歉,我是 stackoverflow 的新手
    猜你喜欢
    • 2021-09-22
    • 2018-11-07
    • 2021-11-27
    • 2021-02-14
    • 2020-09-15
    • 2019-06-25
    • 2020-07-15
    • 2021-03-23
    • 1970-01-01
    相关资源
    最近更新 更多