Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Updating the state correctly after fetch data from firestore

I am trying to use Firestore Snapchats to get real time changes on a database. I am using react-native-cli: 2.0.1 and react-native: 0.64.1 .

export const WelcomeScreen = observer(function WelcomeScreen() {
    const [listData, setListData] = useState([]);
    
    const onResult = (querySnapshot) => {
       const items =  []
       firestore()
       .collection("Test")
       .get()
       .then((querySnapshot) => {
           querySnapshot.forEach(function(doc) {
             const tempData = {key: doc.id, data: doc.data}
              items.push(tempData);
           });
           setListData(items)
        });
      }
      
      const onError = (error) => {
        console.error(error);
      }
      
      firestore().collection('Test').onSnapshot(onResult, onError);

}

Every thing is working perfectly, until I use setListData to update the data list. The App does not respond anymore and I get a warning message each time I try to add or delete data from the database

Please report: Excessive number of pending callbacks: 501. Some pending callbacks that might have leaked by never being called from native code

I am creating a deadlock by setting the state this way?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

First, you don’t want to set up a snapshot listener in the body of your component. This results in a growing number of listeners, because every time you render you add a new listener, but every listener results in rendering again, etc. So set up the listener just once in a useEffect:

const [listData, setListData] = useState([]);

useEffect(() => {
  function onResult(querySnapshot) {
    // ...
  }
  function onError(error) {
    console.log(error);
  }

  const unsubscribe = firestore().collection('Test').onSnapshot(onResult, onError);
  return unsubscribe;
}, []);

In addition, your onResult function is going to get called when you get the result, and yet you’re having it turn around and immediately doing a get to re-request the data it already has. Instead, just use the snapshot you’re given:

function onResult(querySnapshot) {
  const items = []
  querySnapshot.forEach(function(doc) {
    const tempData = {key: doc.id, data: doc.data()}
    items.push(tempData);
  });
  setListData(items);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading