我在我的React Native應用程式中使用了很多Firestore快照。我還使用了React hooks。程式碼看起來像這樣:
useEffect(() => { someFirestoreAPICall().onSnapshot(snapshot => { // 當元件初始化載入時,將所有載入的資料加入狀態。 // 當Firestore上的資料發生變化時,我們在此回呼中接收到更新, // 然後根據當前狀態更新UI });; }, []);
起初,我認為useState
是儲存和更新UI的最佳hook。然而,根據我的useEffect
hook的設置,它帶有一個空的依賴數組,當快照回調被觸發並且我嘗試使用新更改修改當前狀態時,當前狀態是未定義的。我認為這是由於閉包引起的。我能夠透過使用useRef
和forceUpdate()
來解決這個問題,程式碼如下:
const dataRef = useRef(initialData); const [, updateState] = React.useState(); const forceUpdate = useCallback(() => updateState({}), []); useEffect(() => { someFirestoreAPICall().onSnapshot(snapshot => { // 如果快照資料被新增 dataRef.current.push(newData) forceUpdate() // 如果快照資料被更新 dataRef.current.find(e => some condition) = updatedData forceUpdate() });; }, []); return( // 使用dataRef.current的JSX )
我的問題是,我是否正確地使用了useRef
以及與useState
不同的forceUpdate
?我覺得在整個應用程式中更新useRef
hook並且呼叫forceUpdate()
並不正確。當嘗試使用useState
時,我嘗試將狀態變數新增至依賴數組中,但結果導致無限循環。我只想要初始化快照函數一次,並且希望元件中的有狀態資料隨著後端的變化而隨時間更新(在onSnapshot回調中觸發)。
如果你結合使用 useEffect 和 useState,會更好。 useEffect 負責設定和解除監聽器,useState 只需要負責你需要的資料。
然後你可以在你的應用程式中直接引用 useState 鉤子中的 "data"。
A simple useEffect worked for me, i don't need to create a helper function or anything of sorts,
一個簡單的useEffect對我很有用,我不需要創建任何幫助函數或類似的東西,