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 one rror = (error) => {
console.error(error);
}
firestore().collection('Test').onSnapshot(onResult, one rror);
}
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?
CodePudding user response:
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 one rror(error) {
console.log(error);
}
const unsubscribe = firestore().collection('Test').onSnapshot(onResult, one rror);
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);
}
CodePudding user response:
Dharmik, it is okay to use useState outside of functional components, if said component is a custom hook, this doesn't look like it and I would probably make it a hook, or return the answers to call it in a functional component with a setter.