#reactjs #google-cloud-firestore #react-hooks #use-effect
#reactjs #google-облако-firestore #реагирующие крючки #использовать-эффект
Вопрос:
У меня есть следующая подписка на firebase, которая создается useEffect
в простом функциональном компоненте:
const [messages, setMessages] = useState([]);
useEffect(() => {
const unsubscribe = db.collection('chatChannels').doc('general')
.onSnapshot(snapshot => {
if (snapshot.data()) {
setMessages(snapshot.data().messages);
} else {
console.log('it was empty');
}
})
return () => {
unsubscribe();
};
});
Это предназначено для извлечения содержимого messages
поля из general
документа в chatChannels
коллекции. Другими словами, я пытаюсь настроить простой общедоступный канал обмена мгновенными сообщениями.
Проблема в том, что я считаю, что это проблематично для производительности. Каждый раз, когда отправляется сообщение, состояние обновляется, подписка отменяется, useEffect
срабатывает, и подписка создается заново. Это много ненужных сетевых обходов. Я бы хотел этого избежать. Но я не могу придумать способ настроить это так, чтобы новое сообщение обновляло состояние без изменения подписки каждый раз.
Я хочу отказаться от подписки, когда компонент полностью отключен, но не при каждом его обновлении. Мне неясно, возможно ли это.
Ответ №1:
Передайте пустую зависимость []
useEffect
перехватчику, и она будет вести componentDidMount
себя и componentWillUnmount
.
useEffect(() => {
const unsubscribe = db.collection('chatChannels').doc('general')
.onSnapshot(snapshot => {
if (snapshot.data()) {
setMessages(snapshot.data().messages);
} else {
console.log('it was empty');
}
})
return () => {
unsubscribe();
};
}, []);
Вот ссылка на официальную useEffect
документацию: https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects