Как вручную удалить слушателей Firebase Firestore? - PullRequest
0 голосов
/ 01 марта 2019

Из этого ответа SO я понимаю, что мы должны вручную удалить прослушиватели Firebase. Как я могу это сделать в следующем случае использования?Моя успешная попытка показана в следующем коде.

Я тоже пытался использовать некоторые идеи из этого ответа. Но безуспешно.

Что я делаю не так?

import React, { Component } from 'react';
// redacted for brevity
import firebase from '@firebase/app';
import '@firebase/firestore';

class CRUDContainer extends Component {
  state = {
    items: [],
    path: null,
    isError: false,
    isLoading: true,
  };

  componentWillUnmount () {
    // cancel subscriptions and async tasks to stop memory leaks
    this.unsubscribe(this.path);
  }

  unsubscribe = path => path && firebase.firestore().collection(path).onSnapshot(() => {})

  getItems = path => {
    const out = [];
    const db = firebase.firestore();
    if(!db) return;
    db.collection(path)
      .orderBy('timestamp', 'desc')
      .get()
      .then(querySnapshot => {
        querySnapshot.forEach(doc => {
          out.push(doc.data());
        });
        return out;
      })
      .then(result => {
        const newState = {
          path,
          items: result,
          isError: false,
          isLoading: false,
        };
        this.setState(newState);
        return result;
      })
      .then(() => {
        this.unsubscribe(path);
        return path;
      })
      .catch(error => {
        console.error('Error getting documents: \n', error);
        const newState = {
          isError: true,
          isLoading: false,
        };
        this.setState(newState);
      });
  };

  Child = ({ match: { params: { id }}}) => {
    // redacted for brevity
    getItems(path);
    return (
      this.state.isLoading
      ?
      <Loading/>
      :
      (
        this.state.isError
        ?
        <ErrorMessage/>
        :
        (items && (
        <CRUDView items={items} />
      )))
    )
  };

  render() {
    return <Route path="/:id" component={this.Child} />
  }
}

export default CRUDContainer;
...