REACT JS class Lifecycles: How to put http request in ComponentdidUpdate?

Viewed 34

I have a http request to call once the prop taken from redux store updates as shown below:

const mapStateToProps = state => {
  console.log(state.queryBuild);
  return {
      queryBuilderObject: state.queryBuild,
  }

}

export default connect(mapStateToProps, null)(SummaryView);

Here is my componentdidupdate function:

async componentDidUpdate()
  {
    //console.log("Component unmount detected");
    //console.log(this.props.queryBuilderObject);
    this.setState({state: {
      ...this.state,
      isLoading: true,
    }});
    await axios.post(ApiEndPoints.getSummaryDataByQueryBuilder,this.props.queryBuilderObject,{timeout: axiosTimeOut})
    .then(response => {
      console.log("REsponse:");
      console.log(response);
          this.setState({state: {
            ...this.state,
            isLoading: false,
          }});
    })
    .catch(error => console.log("Error: " + error.message));


  }

now here's the problem... somehow I want to only make an http request if props.queryBuilderObject changes that comes from redux store. But when I am going this way, I am entering into an infinite loop as I am setting state and hence componentdidupdate is triggered everytime.

Can someone suggest the right way to do so?

1 Answers

componentDidUpdate receives the previous props and state as arguments, you can check the previous props' queryBuilderObject against the current props' queryBuilderObject and if they are not equal do the POST request.

componentDidUpdate(prevProps, prevState, snapshot)

You may call setState() immediately in componentDidUpdate() but note that it must be wrapped in a condition

If you update state from this lifecycle function without a conditional check then it will likely cause infinite render looping.

There is also no need to spread in existing state in the setState function; setState does a shallow merge of state updates.

async componentDidUpdate(prevProps) {
  if (prevProps.queryBuilderObject !== this.props.queryBuilderObject) {
    this.setState({ isLoading: true });
    await axios
      .post(
        ApiEndPoints.getSummaryDataByQueryBuilder,
        this.props.queryBuilderObject,
        { timeout: axiosTimeOut }
      )
      .then((response) => {
        this.setState({ isLoading: false });
      })
      .catch((error) => console.log("Error: " + error.message));
  }
}
Related