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).
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.
You can then directly reference "data" in the useState hook in your application.
A simple useEffect worked for me, i don't need to create a helper function or anything of sorts,
A simple useEffect works for me, I don't need to create any helper functions or anything like that,