I'm reading from my firebase realtime database when my component loads to update a state with the returned data. Whenever the component loads, it gets the data from the database 8 times, and this causes React to give an error since the state is updated too many times in quick succession.
I've tried using both the onValue listener and the get function, and they both do the same thing on page load. If instead, I do not call them on page load, and either onValue or get runs manually or from the database being updated, it runs only once as expected.
The component:
export default function FoodItem(props) {
const [foods, setFoods] = useState()
const db = getDatabase()
// creating the onValue listener (below) creates the same issue
// const mealRef = ref(db, (props.userId + "/" + props.date + "/" + props.meal))
// onValue(mealRef, (snapshot) => {
// const data = snapshot.val()
// console.log(data)
// setFoods(data)
// })
useEffect(() => {
console.log("getFoods")
const dbRef = ref(getDatabase())
get(child(dbRef, (props.userId + "/" + props.date + "/" + props.meal))).then((snapshot) => {
if (snapshot.exists()) {
console.log(snapshot.val())
// setFoods(data)
} else {
console.log("No data available")
}
}).catch((error) => {
console.error(error)
})
}, [])
return (
...
)
}
The console output from the code above
If instead of using useEffect, I call get with a function (for example, with onClick, it only gets the data once as expected:
function getFoods() {
console.log("getFoods")
const dbRef = ref(getDatabase())
get(child(dbRef, (props.userId + "/" + props.date + "/" + props.meal))).then((snapshot) => {
if (snapshot.exists()) {
console.log(snapshot.val())
// setFoods(data)
} else {
console.log("No data available")
}
}).catch((error) => {
console.error(error)
})
}
How do I make it only run once when the component loads?