Reputation: 11039
I fetch data in React Native with fetch(url, ...)
in my componentDidMount()
method.
So my class looks something like
class Posts extends Component {
state = {
posts: []
};
componentDidMount() {
fetch('https://...').then(res => res.json()).then(res => {
this.setState({ posts: res.posts });
}
}
render() {
return <FlatList data={this.state.posts} ... />;
}
}
It worked fine all until I started using redux
and redux-persist
.
Now I get the warning Warning: Can only update a mounted or mounting component. ...
.
I don't understand why this is happening since it should be mounted if it's called in componentDidMount
.
I am wondering if I need to abort fetching in componentWillUnmount
or if I should actually fetch the data to the redux store instead of only storing the data temporarily in the 'local component'. When I open most other apps, it seems the data is already loaded when I open the app - is this due to very fast data retrieval or are they saving the data in a persisting store?
I have seen some projects where they use if (this.isMounted) { .. }
inside componentDidMount
, but as I understand the lifecycle of this method, the component would always have been mounted at this time. Also, it seems isMounted
is deprecated.
What am I doing wrong? The issue only occurs when I start the app, so there's no problem if I navigate to another route and then back to this route.
Upvotes: 2
Views: 1010
Reputation: 5442
Since fetch
is async, the component might not be mounted when the data arrives. when the arrow functions inside your then
s are being called, the component had already finished mounting and continued to rendering probably. This the nature of Promise
.
You should make sure the component is still mounted when setting it's state, like this:
class Posts extends Component {
state = {
posts: []
};
componentDidMount() {
this.mounted = true;
fetch('https://...').then(res => res.json()).then(res => {
if(this.mounted) this.setState({ posts: res.posts });
}
}
componentWillUnmount() {
this.mounted = false;
}
render() {
return <FlatList data={this.state.posts} ... />;
}
}
Upvotes: 3