В настоящее время я создаю список дел в React, который извлекает задачи из Firestore и сохраняет их локально в массиве с помощью хуков состояния: const [todoList, setTodoList] = useState([])
. При кодировании я столкнулся с некоторыми препятствиями, в основном потому, что функция Firestore onSnapshot
, похоже, не работает должным образом с React. Код моментального снимка вызывается при загрузке (для получения существующих задач) и при создании новой задачи. Код моментального снимка для добавления изменений в массив:
todoReference.onSnapshot(colSnapshot => {
colSnapshot.docChanges().forEach(change => {
if (change.type === 'added') {
const taskData = change.doc.data();
todoList.push(taskData);
}
});
setTodoList(todoList); // "update state" using new array
});
Есть несколько проблем, которые всплывают, когда я пробую разные варианты этого (нажатие на пустой массив, а затем объединение двух массивов вместе и т. Д. c.):
Состояние списка задач не сохраняется на новом снимке. Например, создание новой задачи task2
обновляет todoList до [task2]
, но создание другой задачи task3
после этого приводит к исчезновению первой задачи и обновлению массива до [task3]
вместо [task2, task3]
.
onSnapshot продолжает получать одни и те же задачи, несмотря на то, что они были получены ранее. Например, при загрузке начальный список todoList обновляется до [task1, task2, task3]
. При создании новой задачи и повторном вызове функции моментального снимка я ожидаю, что todoList будет обновлен до [task1, task2, task3, task4]
. Однако вместо этого мне возвращен вариант [task1, task2, task3, task1, task2, task3, task4]
, который объединяется всякий раз, когда функция моментального снимка вызывается снова.
Эта проблема, похоже, возникает только в React, а не в нативном JavaScript ( задачи создаются и извлекаются отлично, без дубликатов). Некоторые решения, которые я пробовал, заключаются в том, чтобы обернуть все в onEffect (который, как я считаю, дал мне первую проблему, если я не передал todoList
в качестве зависимости, и если бы я сделал, то бесконечно l oop) и вызов функции моментального снимка через unsubscribe()
(что все еще дало мне вторую проблему).