How to initialise Firebase in ReactJS using the useSyncExernalStore()
hook instead of useEffect()
After reading You Might Not Need an Effect I wanted to connect my new shiny React app with Firestore without doing it the way I usually do. That is, using the useEffect
hook.
useSyncExternalStore
to the rescue! I'm not going into details of how to set up your create-react-app or how to setup Firestore. In short, here it is:
Setup react with
npx create-react-app
npm install firebase
Setup firebase in firebase dev console
Create 3 files:
db/firebase.ts
,hooks/useFireStore.ts
andfirebaseStore.ts
Lets get to the code!! 🤓
Initialise firebase according to their docs in firebase.ts
// Import the functions you need from the SDKs you need | |
import { initializeApp } from "firebase/app"; | |
import { getFirestore } from "firebase/firestore"; | |
// TODO: Add SDKs for Firebase products that you want to use | |
// https://firebase.google.com/docs/web/setup#available-libraries | |
// Your web app's Firebase configuration | |
// For Firebase JS SDK v7.20.0 and later, measurementId is optional | |
const firebaseConfig = { | |
apiKey: FIREBASE_API_KEY, | |
authDomain: FIREBASE_AUTHDOMAIN, | |
projectId: FIREBASE_PROJECT_ID, | |
storageBucket: FIREBASE_STORAGE_BUCKET, | |
messagingSenderId: FIREBASE_MESSAGING_SENDER_ID, | |
appId: VITE_FIREBASE_APP_ID, | |
measurementId: VITE_FIREBASE_MEASUREMENT_ID, | |
}; | |
// Initialize Firebase | |
const app = initializeApp(firebaseConfig); | |
export const db = getFirestore(app); |
Setup your store in firebaseStore.ts
(we don't really have a third party store but instead we rely on firebase and its caching to act as our store).
let data: string | undefined; | |
const firebaseStore = { | |
getSnapshot: () => { | |
return data; | |
}, | |
subscribe: (callback: () => void) => { | |
const unsub = onSnapshot(doc(db, "my-collection", "my-document"), (doc) => { | |
data = doc.data()?.test; | |
callback(); | |
}); | |
return () => { | |
data = undefined; | |
unsub(); | |
}; | |
}, | |
}; | |
export default firebaseStore |
Let's put it in a custom hook useFirestore.ts
const useFirestore = () => { | |
const data = useSyncExternalStore(firebaseStore.subscribe, firebaseStore.getSnapshot); | |
return data; | |
}; |
Lastly, lets use it in our react component App.tsx
function App() { | |
const data = useFirestore(); | |
return <h1>{data}</h1>; | |
} |
Now whenever Firestore updates the listener will be triggered in firebaseStore.ts
and update the data in our custom hook and our component will rerender with the new data. Tadaaa! 🎉
Top comments (5)
Great article. Keep pushing new articles. Thank You.
Very nice! I think this react hook is really underrated, I am very glad to see education content about it!
Thanks! Indeed, I was surprised how hard it was to find more content about this hook outside of the official docs.
You might like this video by Jack Herrington, he also mentioned this hook in combination with react context, could server as an inspiration for your next article :)
Great, thank you!