Reputation: 4256
I have a RN app where I'm reading in data from Firebase when a component mounts (a 'Favorites' screen), and setting it as the state for the Favorites component to then render.
But when I'm on another screen and add an item to the favorites database in firebase, I'm getting a yellow warning of:
Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component.
This pops up when I add a new item that would then update the data in firebase.database().ref('userfavs').child(DeviceID)
. To be clear, the functionality doesn't seem broken and when I console log out the datalist
array from the state, the new "favorited" item is added on there as expected..
class Favorites extends React.Component {
constructor(props) {
super(props);
this.state = {
datalist: []
};
this.favsRef = firebase.database().ref('userfavs').child(DeviceID);
}
listenForItems(favsRef) {
favsRef.on('value', (snap) => {
var items = [];
snap.forEach((child) => {
items.push(child.val()
);
});
});
this.setState({
datalist: items
});
});
}
componentWillMount() {
this.listenForItems(this.favsRef);
}
render() {
console.log('state datalist:', this.state.datalist);
... }}
I don't really understand this error, because i've put the listenForItems
call under componentWillMount
, so whenever I navigate to the "Favorites" screen and this component loads, it pulls down the most recent data in Firebase.
Thanks!
Upvotes: 0
Views: 596
Reputation: 1452
You´re probably adding a listener that keep your Favorites component in memory after it has unmounted.
According to the docs, there is a .off
method for detaching the listener:
https://firebase.google.com/docs/reference/js/firebase.database.Query#off
Solution would be something like:
class Favorites extends React.Component {
constructor(props) {
super(props);
this.state = {
datalist: []
}
this.favsRef = firebase.database().ref('userfavs').child(DeviceID);
this.listen = snap => {
const dataItems = snap.map(child => child.val())
this.setState({dataItems})
}
}
componentDidMount() { this.favsRef.on('value', this.listen) }
componentWillUnmount() { this.favsRef.off('value', this.listen) }
Upvotes: 1