处理reference type 的 useEffect dependency(通过useRef hook)
当通过字面量语法设置的参数被作为useEffect dependency时,由于数组或对象本身是reference type。这样在component 每次re-render时,即使一模一样的输入也会因为存储地址的不同而被React 认为dependency 发生变化,进而触发 infinite loop。
解决此问题
方案一:useRef hook
源码:
import { useEffect, useState, useRef } from "react"
export const useCollection = (collection, _query, _orderBy) => {
const [documents, setDocuments] = useState(null)
const [error, setError] = useState(null)
// if we don't use a ref --> infinite loop in useEffect
// _query is an array and is "different" on every function call
const query = useRef(_query).current
const orderBy = useRef(_orderBy).current
useEffect(() => {
let ref = projectFirestore.collection(collection)
if (query) {
ref = ref.where(...query)
}
if (orderBy) {
ref = ref.orderBy(...orderBy)
}
const unsubscribe = ref.onSnapshot(snapshot => {
let results = []
snapshot.docs.forEach(doc => {
console.log(doc)
results.push({...doc.data(), id: doc.id})
});
// update state
setDocuments(results)
setError(null)
}, error => {
console.log(error)
setError('could not fetch the data')
})
// unsubscribe on unmount
return () => unsubscribe()
}, [collection, query, orderBy])
return { documents, error }
}
方案二:
用JSON.stringify() 函数包裹变量,似乎也是近似可行的方法之一。(待考证)