简体   繁体   English

React Native firebase 函数在 useEffect 下无法正确获取

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM