Even though there are many questions with the same subject line, I could not get an answer for my problem.
Problem
I have a select dropdown. On click of which, I call an Api which fetches some key values. I consider this set of key value input fields as a ponent. So each and every time onChange of my select drop-down, I have used lifecycle methods to handle API Calls. Also, I record these input key values and send back their state to parent ponent.
According to ReactJS lifecycle methods:
I use
ponentDidMount To call the API for the first time after initial render. This works.
ponentDidUpdate To call the API for subsequent API calls on select drop-down change. But here is the problem. When I try to update the state of input fields the program falls into an infinite loop and hence there are infinite API calls. I am pretty sure after debugging that the problem is with setState(), But I couldnt find the best way to handle states in ponentDidUpdate method.
This link exactly replicates my problem but i want a standardized solution
Hope this is clear. Thanks for the help in advance!
Even though there are many questions with the same subject line, I could not get an answer for my problem.
Problem
I have a select dropdown. On click of which, I call an Api which fetches some key values. I consider this set of key value input fields as a ponent. So each and every time onChange of my select drop-down, I have used lifecycle methods to handle API Calls. Also, I record these input key values and send back their state to parent ponent.
According to ReactJS lifecycle methods:
I use
ponentDidMount To call the API for the first time after initial render. This works.
ponentDidUpdate To call the API for subsequent API calls on select drop-down change. But here is the problem. When I try to update the state of input fields the program falls into an infinite loop and hence there are infinite API calls. I am pretty sure after debugging that the problem is with setState(), But I couldnt find the best way to handle states in ponentDidUpdate method.
This link exactly replicates my problem but i want a standardized solution
Hope this is clear. Thanks for the help in advance!
Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Jun 21, 2016 at 6:44 bks4linebks4line 5153 gold badges10 silver badges24 bronze badges5 Answers
Reset to default 7This is spelled out pretty clearly in the docs:
ponentDidUpdate(prevProps) {
// Typical usage (don't forget to pare props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
You may call setState() immediately in ponentDidUpdate() but note that it must be wrapped in a condition like in the example above, or you’ll cause an infinite loop.
You can use setState()
within ponentDidUpdate()
. But you have to use the condition for that. Otherwise, it get infinite loop.
As the example,
ponentDidUpdate(){
if(this.props.id !== this.state.id) {
this.setState({
id: this.props.id
});
}
}
Yes you cannot setState() inside ponentDidUpdate it would lead to infinite loop.Instead you can call a function onChange event and change the state there.
This happens because setState triggers a call to ponentDidUpdate.
When ponentDidUpdate is called, setState does not check whether or not state change has occurred. It simply calls ponentDidUpdate again and again, which leads to stackoverflow.
class Component extends React.Component{
constructor(props){
super(props);
this.state = {changeState: false}
}
ponentDidMount(){
this.setState({changeState: true});
}
ponentDidUpdate(){
this.setState({changeState: false});
}
}
Here, first changeState is set to false in constructor, and then ponentDidMount is triggered, which sets state of changeState to true. This state change triggers ponentDidUpdate, which sets the state of changeState again to true. This triggers ponentDidUpdate again and again.
You have to check the real difference between two state objects. Below you can find my solution, My state object has movies, which is an array of objects. I edited and movie and then paring these two arrays.
async ponentDidUpdate(prevProps, prevState) {
if (prevState.movies.filter (e => this.state.movies.includes(e))) {
const response = await axios.get("http://localhost:3002/movies");
this.setState({ movies: response.data })
}
}