哪个react-hooks与 firestore onsnapshot 一起使用?

IT技术 reactjs firebase google-cloud-firestore react-hooks react-native-firebase
2021-03-27 20:17:24

我在我的本机应用程序中使用了很多 firestore 快照。我也在使用 React 钩子。代码如下所示:

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

    });;
}, []);

起初我认为useState这是存储和更新 UI 的最佳钩子。但是,根据我的useEffect钩子设置空依赖数组的方式,当快照回调被更新的数据触发并且我尝试用新的更改修改当前状态时,当前状态是未定义的。我相信这是因为关闭。我能得到它的周围使用useRefforceUpdate()像这样:

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
)

我的问题是我通过useRef与 a 一起使用forceUpdate而不useState是以不同的方式正确地做到这一点吗?我不得不更新一个useRef钩子并forceUpdate()在我的应用程序中调用似乎是不对的尝试时,useState我尝试将状态变量添加到依赖项数组,但结果是无限循环。我只希望快照函数被初始化一次,并且组件中的有状态数据随着后端的变化(在 onSnapshot 回调中触发)而随着时间的推移而更新。

3个回答

如果将 useEffect 和 useState 结合起来会更好。UseEffect 将设置和分离侦听器,useState 可以只负责您需要的数据。

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()
}, []);

然后您可以从应用程序中的 useState 挂钩中引用“数据”。

因为这是一个功能组件,所以我不使用“this”关键字。此外,问题在于setData它在快照侦听器中没有按照应有的方式工作。当我setData在侦听器内部使用时,数据在组件的下一次渲染中丢失。因此,在初始加载后,下次后端发生某些变化并且侦听器触发时,我想查看并修改当前,data但即使我在初始加载时设置了它,它也未定义。我访问数据的唯一方法是使用useRefwhich 来保存data渲染之间的数据
2021-06-13 20:17:24
为什么需要使用“this”关键字?如果您不想更改数据,请不要使用实时侦听器,您可以改用简单的 get() 调用。
2021-06-15 20:17:24
我认为问题在于带有onSnapshotreact-hooks的侦听器本身。如果我在 useEffect 中设置状态, []但不是 inside onSnapshot,事情似乎工作正常。
2021-06-20 20:17:24

我发现在 onSnapshot() 方法内部我无法访问状态(例如,如果我 console.log(state) 我会得到一个空值。

创建一个有用的辅助函数,但我不确定这是否是 hack-y 解决方案,但类似于:

[state, setState] = useState([])

stateHelperFunction = () => {
//update state here
setState()
}

firestoreAPICall.onSnapshot(snapshot => {
stateHelperFunction(doc.data())
})

use 可以使用 set hook 上的回调获取 currentState

const [state, setState] = useState([]);
firestoreAPICall.onSnapshot(snapshot => {
 setState(prevState => { prevState.push(doc.data()) return prevState; })
})

prevState 将具有当前状态值