I'm working on a project that uses Firebase and React hooks. Before the web application is loaded i want to get all the data from Firebase by running the query as shown below.
const [lists, setLists] = useState([]);
useEffect(() => {
const dataArray = [];
/** handleWidgets */
listsRef
.once('value', snap => {
snap.forEach(function(result) {
firebase
.database()
.ref('lists')
.child(result.key)
.on('value', snap => {
if (snap.val()) dataArray.push(snap.val());
});
});
})
.then(function() {
setLists(dataArray);
});
}, [lists]);
For some reason the useEffect is always running and creating a huge performance issue. Is there a better way to use Firebase queries with React Hooks like useEffect? Now if lists is changed or not the useEffect is always running.
UPDATED:
A couple of things:
1) Your useEffect
is subscribing to lists
which is being set within this useEffect
, so it's triggering a re-run.
2) You're attempting to update the item and then re-fetch all of the data including the updated item. You don't need to do this. Once you have your "initial state" from Firebase, all of the modifications can happen to that list within state. Yes, you'll call to do the add/update/delete, but you don't need to call to get a brand new list each time because you know what information you've changed and can simply update your state list to reflect this while also calling to actually update the underlying data so that when you navigate away your list from Firebase reflects the list that was in state.
SO!
Remove the lists
from the []
at the end so your code so it only runs on mount and looks like the following:
const [lists, setLists] = useState([]);
useEffect(() => {
const dataArray = [];
/** handleWidgets */
listsRef
.once('value', snap => {
snap.forEach(function(result) {
firebase
.database()
.ref('lists')
.child(result.key)
.once('value', snap => {
if (snap.val()) dataArray.push(snap.val());
});
});
})
.then(function() {
setLists(dataArray);
});
}, []); // removed lists from subscription []
Then, let's say in an add method, it would look something like the following:
addItem = listItem => {
// make copy of array in state
const newLists = [...lists];
// add item to list
newLists.push(listItem);
// update list in DB with firebase
/* firebase call here with new list item */
// update state lists with new array that has new item
setLists(newLists)
}
And so on and so forth from the update/delete methods. You're going to just use that state value without ever calling Firebase for an updated list because you already have it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.