Can't update state react, returning infinite loop

Viewed 53

So, this is my state, and is all fine.

state = {
    prazoAdic: this.props.form.prazoAdicCad,
    prazoMedio: this.props.form.prazoMedio,
    tableData: [],
  };

This function "grupoDeVendaCheck()" needs to update the state "tableData" with the value "newObj", and this value (newObj) its good.

grupoDeVendaCheck = () => {
    const { current } = this.props.dropdown;

    const newPrazo = current.products.map((item) => ({
      ...item,
      sf_prazo1__c: parseInt(item.sf_prazo1__c || 0) + this.state.prazoMedio,
    }));

    const newObj = Object.values(
      newPrazo.reduce((acc, el) => {
        const key = el.grupoVendas + "_" + el.sf_prazo1__c;
        if (!acc[key])
          acc[key] = {
            group: el.grupoVendas,
            term: el.sf_prazo1__c,
            value: 0,
          };
        const bruto = el.sf_quantity * el.sf_sum_of_pairs__c * el.sf_list_price;
        acc[key].value += bruto;

        return acc;
      }, {})
    );

    this.setState({ tableData: newObj }); // This is the problem

    console.log(newObj, "object");
  };

Above we have the componentDidUpdate, and I think that is working fine too.

componentDidUpdate(prevProps, prevState) {
    if (
      prevProps.form.prazoAdicCad !== prevState.prazoAdic ||
      prevProps.form.prazoMedio !== prevState.prazoMedio
    ) {
      this.setState({ prazoAdic: prevProps.form.prazoAdicCad });
      this.setState({ prazoMedio: prevProps.form.prazoMedio });
    } else if (typeof prevState.prazoAdic === "number") {
      this.grupoDeVendaCheck();
    }
  }

So, what is the deal, when I comment the setState on the method "grupoDeVendaCheck()" and run, he shows me the correct value of the "newObject", look:

enter image description here

But when I put the setState, to change the value of the state "tableData", this is the result:

enter image description here enter image description here

I just want to update my state with this value, but I can't for some reason, I already try to use arrow inside setState, but I think I did it wrong.

If anyone can help me I would be very grateful

1 Answers

componentDidUpdate is called every time you use the setState function, so obviously you have to be very careful not to cause a loop.

Its quite hard to get my head round your code out of context, but I think is happening is:

The first condition you use is this

 if (
      prevProps.form.prazoAdicCad !== prevState.prazoAdic ||
      prevProps.form.prazoMedio !== prevState.prazoMedio
    ) {

If that is false, it calls the function grupoDeVendaCheck()

That function updates the state, but it only updates tableData

prazoAdicCad, prazoAdic, prazoMedio and prazoMedio remain unchanged so when you use this.setState({ tableData: newObj }), componentDidUpdate is called again and the condition is the same. This means grupoDeVendaCheck is called again.

You need to either effect the state used for the condition at the same time like this:

this.setState({ tableData: newObj, prazoAdic: somethingNew }) This would break the cycle

Or find another effect to trigger the 'grupoDeVendaCheck' function in the first place rather than using componentDidUpdate

EDIT Just thinking a little more about it - it may be a good idea to move your tableData to the parent that is setting the form props, and update it with a callback. You would have more control at that level.

Related