Какой реактивный крючок использовать с firestore onsnapshot? - PullRequest
2 голосов
/ 28 января 2020

Я использую множество моментальных снимков 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 будет лучшим хуком для хранения и обновления пользовательского интерфейса. Однако, основываясь на том, как мой хук useEffect настроен с пустым массивом зависимостей, когда обратный вызов моментального снимка запускается с обновленными данными, и я пытаюсь изменить текущее состояние новыми изменениями, текущее состояние не определено. Я считаю, что это из-за закрытия. Я могу обойти это, используя useRef с forceUpdate(), например так:

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 вместе с forceUpdate вместо useState по-другому? Неправильно, что мне приходится обновлять useRef ловушку и вызывать forceUpdate() во всем приложении. При попытке useState я попытался добавить переменную состояния в массив зависимостей, но в итоге получился бесконечный l oop. Я только хочу, чтобы функция моментального снимка была инициализирована один раз, а данные о состоянии в компоненте будут обновляться с течением времени по мере того, как на бэкенде будут происходить изменения (которые запускаются в обратном вызове onSnapshot).

1 Ответ

1 голос
/ 29 января 2020

Было бы лучше, если вы объедините 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 umount or you will create a memory leak
       retun () => unsubscribe()
}, []);

Затем вы можете просто сослаться на data из ловушки useState в вашем приложении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...