title: Which react hook to use with firestore onsnapshot?
body: <p>I use a lot of firestore snapshots in my react native application. I am also using React hooks. The code looks something like this:</p>
  
  <pre><code>useEffect(() =&gt; {
      someFirestoreAPICall().onSnapshot(snapshot =&gt; {
  
          // 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
  
      });;
  }, []);
  </code></pre>
  
  <p>At first I assumed <code>useState</code> would be the best hook to store and update the UI. However, based on the way my <code>useEffect</code> 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 <code>useRef</code> with a <code>forceUpdate()</code> like so:</p>
  
  <pre><code>const dataRef = useRef(initialData);
  
  const [, updateState] = React.useState();
  const forceUpdate = useCallback(() =&gt; updateState({}), []);
  
  useEffect(() =&gt; {
      someFirestoreAPICall().onSnapshot(snapshot =&gt; {
  
         // if snapshot data is added
         dataRef.current.push(newData)
         forceUpdate()
  
         // if snapshot data is updated
         dataRef.current.find(e =&gt; some condition) = updatedData
         forceUpdate()
  
      });;
  }, []);
  
  return(
  // JSX that uses dataRef.current directly
  )
  </code></pre>
  
  <p>My question is am I doing this correct by using <code>useRef</code> along with a <code>forceUpdate</code> instead of <code>useState</code> in a different way? It doesn't seem right that I'm having to update a <code>useRef</code> hook and call <code>forceUpdate()</code> all over my app. When trying <code>useState</code> 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).</p>