Choosing a React Hook suitable for use with Firestore's onsnapshot
P粉555682718
P粉555682718 2023-08-24 13:48:51
0
2
448

I use Firestore snapshots a lot in my React Native app. I also used React hooks. The code looks like this:

useEffect(() => { someFirestoreAPICall().onSnapshot(snapshot => { // When the component initially loads, add all loaded data to the state. // When the data on Firestore changes, we receive updates in this callback, // Then update the UI based on the current state });; }, []);

At first, I thought useState was the best hook to store and update the UI. However, according to the settings of my useEffect hook, which comes with an empty dependency array, when the snapshot callback is fired and I try to modify the current state with new changes, the current state is undefined. I think this is due to closures. I was able to solve this problem by using useRef and forceUpdate() with the following code:

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 the snapshot data is updated dataRef.current.find(e => some condition) = updatedData forceUpdate() });; }, []); return( // JSX using dataRef.current )

My question is, am I using useRef correctly as well as forceUpdate which is different from useState? I feel like updating the useRef hook and calling forceUpdate() throughout the application is not correct. When trying to use useState, I tried adding the state variable to the dependency array, but it resulted in an infinite loop. I only want to initialize the snapshot function once, and want the stateful data in the component to update over time as the backend changes (triggered in the onSnapshot callback).

P粉555682718
P粉555682718

reply all (2)
P粉806834059

It will be better if you combine useEffect and useState. useEffect is responsible for setting and disabling the listener, and useState is only responsible for the data you need.

const [data, setData] = useState([]); useEffect(() => { const unsubscribe = someFirestoreAPICall().onSnapshot(snap => { const data = snap.docs.map(doc => doc.data()) this.setData(data) }); //记得在卸载组件时取消实时监听器,否则会造成内存泄漏 return () => unsubscribe() }, []);

You can then directly reference "data" in the useState hook in your application.

    P粉165522886

    A simple useEffect worked for me, i don't need to create a helper function or anything of sorts,

    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()); }) }) }, [])

    A simple useEffect works for me, I don't need to create any helper functions or anything like that,

    useEffect(() => { const colRef = collection(db, "data") //实时更新 onSnapshot(colRef, (snapshot) => { snapshot.docs.forEach((doc) => { setTestData((prev) => [...prev, doc.data()]) // console.log("onsnapshot", doc.data()); }) }) }, [])
      Latest Downloads
      More>
      Web Effects
      Website Source Code
      Website Materials
      Front End Template
      About us Disclaimer Sitemap
      php.cn:Public welfare online PHP training,Help PHP learners grow quickly!