简体   繁体   English

为什么在导出到另一个文件时 onSnapshot 侦听器不起作用

[英]Why isn't onSnapshot listener working when exported to another file

I had an onSnapshot listener function set up, but once I extracted it to another file it stopped working.我设置了一个 onSnapshot 侦听器函数,但是一旦我将其解压缩到另一个文件中,它就停止工作了。

The code below is in the utilities file.下面的代码在实用程序文件中。

export const getUserCampsites = () => {

      const user = store.getState().authReducer.user 
      let campsitesArr = [];

      //check if user is signed in
      if(user.hasOwnProperty('uid')){ 
            const campsites = db
            .collection('campsites')
            .where('owner', '==', user.uid);

            const unsub = campsites
            .onSnapshot(snapshot => {
                  snapshot.forEach(el => {
                        campsitesArr.push(el.data());
                  })

            });
      
      return {unsub, campsitesArr}
      }
}

And this is what I have in the component:这就是我在组件中的内容:

      const [camps, setCamps] = useState();

      useEffect(() => {
            const res = getUserCampsites()
            if(res) {
                  const campsites = res.campsitesArr
                  setCamps(campsites);
                  return(() => res.unsub())

            }
      }, [user])

When 'setCamps' in the component is called the array comes back empty, but is then filled on a second re-render, am I missing something?当组件中的“setCamps”被调用时,数组返回空,但在第二次重新渲染时被填充,我是否遗漏了什么? Is it supposed to be asynchronous?它应该是异步的吗?

Thanks in advance!提前致谢!

The array campsitesArr in the getUserCampsites function is not reactive, so it is not re returned if its value changes. getUserCampsites 函数中的数组 campsitesArr 不是响应式的,因此如果其值发生变化,则不会重新返回它。 When the getUserCampsites function is called, it inializes the campsitesArr to an empty arr and then it initializes the listener.. However it does not wait for the listener to fetch values before it moves on to the next line which is the return statement.当 getUserCampsites 函数被调用时,它会将 campsitesArr 初始化为一个空的 arr,然后初始化侦听器。然而,它不会等待侦听器获取值,然后才移动到下一行,即 return 语句。 So whenever the return is reached, the campsitesArr is still enter, therefore you always return an empty array.因此,每当达到返回值时,campsitesArr 仍然是输入值,因此您总是返回一个空数组。

The best solution will be to pass a function as an argument to the getUserCampsites, that receives an array of camp sites.最好的解决方案是将函数作为参数传递给 getUserCampsites,它接收一组营地。 This function will be called whenever the listener gets new values.每当侦听器获得新值时都会调用此函数。 For example, you can pass a function to the getUserCampsites that calls setState with the new array of camp sites例如,您可以将一个函数传递给 getUserCampsites,该函数使用新的营地数组调用 setState

Not sure what was wrong, I think it was because the function was returning before the campsitesArr had been populated.不知道出了什么问题,我认为这是因为该函数在 campsitesArr 被填充之前就返回了。

To fix this I passed the setCamps function as a prop and used it directly inside the onSnapshot call back:为了解决这个问题,我将 setCamps 函数作为道具传递并直接在 onSnapshot 回调中使用它:

export const getUserCampsites = (setCamps) => {

      const user = store.getState().authReducer.user 
      

      //check if user is signed in
      if(user.hasOwnProperty('uid')){ 
            const campsites = db
            .collection('campsites')
            .where('owner', '==', user.uid); 

            const unsub = campsites
            .onSnapshot(snapshot => {
                  let campsitesArr = [];
                  snapshot.forEach(el => {
                        campsitesArr.push(el.data());

                  })
                  setCamps(campsitesArr)
            });
            
      
      return unsub
      }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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