Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which react hook to use with firestore onsnapshot?

I use a lot of firestore snapshots in my react native application. I am also using React hooks. The code looks something like this:

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

    });;
}, []);

At first I assumed useState would be the best hook to store and update the UI. However, based on the way my useEffect hook is set up with an empty dependency array, when the snapshot callback gets fired with updated data and I try to modify the current state with the new changes, the current state is undefined. I believe this is because of a closure. I am able to get around it using useRef with a forceUpdate() like so:

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
)

My question is am I doing this correct by using useRef along with a forceUpdate instead of useState in a different way? It doesn't seem right that I'm having to update a useRef hook and call forceUpdate() all over my app. When trying useState I tried adding the state variable to the dependency array but ended up with an infinite loop. I only want the snapshot function to be initialized once and the stateful data in the component to be updated over time as things change on the backend (which fires in the onSnapshot callback).

like image 500
Kevin Quiring Avatar asked Jan 28 '20 08:01

Kevin Quiring


People also ask

What is onSnapshot firestore react?

You can listen to a document with the onSnapshot() method. An initial call using the callback you provide creates a document snapshot immediately with the current contents of the single document. Then, each time the contents change, another call updates the document snapshot.

What are react Firebase hooks?

A set of reusable React Hooks for Firebase. This documentation is for v5 of React Firebase Hooks which requires Firebase v9 or higher.

How do you perform fetch and send with firestore using Reactjs?

Step 1: Create a new React application. We use create-react-app to create our application. Step 2: Install the firebase package in the project using npm. Step 3: Create a new project from the Firebase dashboard by filling in the necessary details and check the format of the data that is stored in Firestore.


2 Answers

It would be better if you combine useEffect and useState. UseEffect will setup and detach the listener, useState can just be 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)
       });

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

Then you can just reference "data" from the useState hook in your app.

like image 146
Josh Pittman Avatar answered Oct 17 '22 17:10

Josh Pittman


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());
            })
        })
    }, [])
like image 2
anshul Avatar answered Oct 17 '22 15:10

anshul