gianlop3z
gianlop3z

Reputation: 97

Maximum update depth exceeded ReactJs componentDidMount

I understood the error, my componentDidUpdate functions is creating an infinite loop, i don't know hot to fix it. I found the two errors that the traceback show me, but i don't know what to do. Here is the submit handler function, it's in the main (logup) component:

submitHandler = event => {          
    event.preventDefault();
    const {month, day, year} = this.state.data;
    this.setState({
       loading: true,
       error: false,
       errors: {},
       data: {
          ...this.state.data,
          foundation: `${month} ${day} de ${year}`
       }
    });

    fetch('http://127.0.0.1:8000/logup/',
       {
          method: 'post',
          headers: {'Content-Type': 'application/json'},
          body: JSON.stringify(this.state.data)
        }).then(response => {
            this.setState({ loading: false });
            if (response.ok) {
                console.log('redirect to social nets');
            } else {
                this.setState({ error: true });
            }
            return response.json();
        }).then(json => {
            if (this.state.error) {
                this.setState({errors: json}) // The traceback give me error right here
            } else {
                console.log(json);
            }
        });    
    };

I also have many Inputs component in the render of that logup component, the traceback show me errors here too.

state = {
    error: false
};

componentDidUpdate() {
      let bad = Object.keys(this.context.errors).includes(this.props.name);
      if (bad) {
         this.setState({ error: true }); // traceback give me error too.        
      };
   };

Traceback

error

Upvotes: 0

Views: 121

Answers (3)

Greg M
Greg M

Reputation: 405

Change

if (bad) {
    this.setState({ error: true }); // traceback give me error too.        
};

to

if (bad && !this.state.error) {
    this.setState({ error: true }); // traceback give me error too.        
};

Using setState inside of componentDidUpdate will cause it to re-render and recall componentDidUpdate. Adding an additional check will help stop this loop.

Upvotes: 0

Piyush Rana
Piyush Rana

Reputation: 667

You should use some type of conditions inside componentDidUpdate for not to trigger state update. Like thus below:

componentDidUpdate(prevProps, prevState) {
      let bad = Object.keys(this.context.errors).includes(this.props.name);
      if (prevState.error !== this.state.error && bad) {
         this.setState({ error: true }); // traceback give me error too.        
      };
   };

Always compare the prevState and currentState value inside componentDidUpdate as in most cases this condition is suffice.

Note : Before starts using componentDidUpdate please refer to the docs as it also provides prevProps and prevState values which are always helpful in such scenarios.

Upvotes: 1

Cory Harper
Cory Harper

Reputation: 1055

In your componentDidUpdate you update state in the following manner:

this.setState({ error: true })

You do so under the condition that this is true:

Object.keys(this.context.errors).includes(this.props.name)

Setting the state causes the component to rerender and also update, so componentDidUpdate will run again. However, it is very likely that when that happens your condition above will still be true. You will thus update state again, and React will not short circuit the state update because you are creating a new object every time. One simple way to save yourself here would be to change your condition to:

      if (bad && !this.state.error) {
         this.setState({ error: true }); // traceback give me error too.        
      };

Upvotes: 2

Related Questions