简体   繁体   English

Firebase 与使用效果清理 function

[英]Firebase with useeffect cleanup function

I'm trying to get all data with the 'public' parameter of a firebase collection and then use useffect, but the console accuses error.我正在尝试使用 firebase 集合的“公共”参数获取所有数据,然后使用 useffect,但控制台指责错误。

I took this structure from firebase's documentation: https://firebase.google.com/docs/firestore/query-data/get-data#get_multiple_documents_from_a_collection我从firebase的文档中获取了这个结构: https://firebase.google.com/docs/firestore/query-data/get-data#get_multiple_documents_from_a_collection

but the console says 'Warning: Can't perform a React state update on an unmounted component.但控制台显示“警告:无法对未安装的组件执行 React state 更新。 This is a no-op, but it indicates a memory leak in your application.这是一个无操作,但它表明您的应用程序中存在 memory 泄漏。 To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function'要修复,请取消 useEffect 清理函数中的所有订阅和异步任务'

So I went to this other page: https://firebase.google.com/docs/firestore/query-data/listen#detach_a_listener所以我去了另一个页面: https://firebase.google.com/docs/firestore/query-data/listen#detach_a_listener

But I'm not using onSnapshot, besides firebase documentation seems wrong to me, since unsub is not a function.但我没有使用 onSnapshot,除了 firebase 文档对我来说似乎是错误的,因为 unsub 不是 function。

useEffect(() => {

        let list = []

        const db = firebase.firestore().collection('events')
        let info = db.where('public', '==', 'public').get().then(snapshot => {
            if (snapshot.empty) {
                console.log('No matching documents.');
                setLoading(false)
                return;
            }
            snapshot.forEach(doc => {
                console.log(doc.id, "=>", doc.data())
                list.push({
                    id: doc.id,
                    ...doc.data()
                })
            })
            setEvents(list)
            setLoading(false)
        })
            .catch(error => {
                setLoading(false)
                console.log('error => ', error)
            })
        return () => info

    }, [])

You need to invoke the listener function to detach and unmount.您需要调用监听器 function 来分离和卸载。 https://firebase.google.com/docs/firestore/query-data/listen#detach_a_listener https://firebase.google.com/docs/firestore/query-data/listen#detach_a_listener

useEffect(() => {

        let list = []

        const db = firebase.firestore().collection('events')
        let info = ...
        return () => info() # invoke to detach listener and unmount with hook

    }, [])

You don't need to clear a .get() , it's like a normal Fetch api call.您不需要清除.get() ,这就像普通的Fetch api 调用一样。

You need to make sure your component is still mounted when you setLoading您需要确保您的组件在setLoading时仍然挂载

Example:例子:

// import useRef
import { useRef } from 'react'
// At start of your component
const MyComponent = () =>{
   const isMounted = useRef(false)
   useEffect(() => {
     isMounted.current = true;
     return () => isMounted.current = false;
  }, [])

   // Your query
   db.where('public', '==', 'public').get().then(snapshot => {
      if(isMounted.current){
        // set your state here. 
      }
   })

  return <div></div>
}

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

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