哪个反应挂钩与 firestore onsnapshot 一起使用?

Which react hook to use with firestore onsnapshot?

我在我的 React Native 应用程序中使用了很多 firestore 快照。我也在使用 React 钩子。代码看起来像这样:

useEffect(() => {
    someFirestoreAPICall().onSnapshot(snapshot => {

        // When the component initially loads, add all the loaded data to state.
        // When data changes on firestore, we receive that update here in this
        // callback and then update the UI based on current state

    });;
}, []);

起初我假设 useState 是存储和更新 UI 的最佳挂钩。但是,根据我的 useEffect 挂钩设置空依赖项数组的方式,当使用更新的数据触发快照回调并且我尝试使用新更改修改当前状态时,当前状态是未定义的。我相信这是因为关闭。我可以使用 useRefforceUpdate() 来绕过它,如下所示:

const dataRef = useRef(initialData);

const [, updateState] = React.useState();
const forceUpdate = useCallback(() => updateState({}), []);

useEffect(() => {
    someFirestoreAPICall().onSnapshot(snapshot => {

       // if snapshot data is added
       dataRef.current.push(newData)
       forceUpdate()

       // if snapshot data is updated
       dataRef.current.find(e => some condition) = updatedData
       forceUpdate()

    });;
}, []);

return(
// JSX that uses dataRef.current directly
)

我的问题是,我以不同的方式使用 useRefforceUpdate 而不是 useState 是否正确?我必须更新 useRef 挂钩并在我的整个应用程序中调用 forceUpdate() 似乎不对。尝试 useState 时,我尝试将状态变量添加到依赖项数组,但以无限循环告终。我只希望快照函数初始化一次,并且组件中的有状态数据随着后端发生变化(在 onSnapshot 回调中触发)而随时间更新。

useEffect和useState结合使用效果会更好。 UseEffect 将设置和分离侦听器,useState 可以只负责您需要的数据。

const [data, setData] = useState([]);

useEffect(() => { 
       const unsubscribe = someFirestoreAPICall().onSnapshot(snap => {
         const data = snap.docs.map(doc => doc.data())
         this.setData(data)
       });

       //remember to unsubscribe from your realtime listener on unmount or you will create a memory leak
       return () => unsubscribe()
}, []);

然后您可以在您的应用中从 useState 挂钩中引用“数据”。

我发现在 onSnapshot() 方法中我无法访问状态(例如,如果我 console.log(state) 我会得到一个空值。

创建一个有用的辅助函数,但我不确定这是否是 hack-y 解决方案,但类似于:

[state, setState] = useState([])

stateHelperFunction = () => {
//update state here
setState()
}

firestoreAPICall.onSnapshot(snapshot => {
stateHelperFunction(doc.data())
})

use 可以在 set hook 上使用回调获取 currentState

const [state, setState] = useState([]);
firestoreAPICall.onSnapshot(snapshot => {
 setState(prevState => { prevState.push(doc.data()) return prevState; })
})

prevState 将具有当前状态值

一个简单的 useEffect 对我有用,我不需要创建辅助函数或任何类似的东西,

useEffect(() => {
        const colRef = collection(db, "data")
        //real time update
        onSnapshot(colRef, (snapshot) => {
            snapshot.docs.forEach((doc) => {
                setTestData((prev) => [...prev, doc.data()])
                // console.log("onsnapshot", doc.data());
            })
        })
    }, [])