title: React - Warning: An update was scheduled from inside an update function
body: <p>I am dealing with a lot of problems about updating states in React for validation purposes, and always my state update after the render or something like that, anyway, I saw that many people solve this using a callback function in the <code>setState</code>, but it always throws the following warning.</p>
  
  <blockquote>
    <p>Warning: An update (setState, replaceState, or forceUpdate) was
    scheduled from inside an update function. Update functions should be
    pure, with zero side-effects. Consider using componentDidUpdate or a
    callback.</p>
  </blockquote>
  
  <p>I tried to update inside <code>componentDidUpdate</code>, but that results in an infinite loop.</p>
  
  <p>This is my <code>setState</code> with the callback function.</p>
  
  <pre><code>state = {
      index: 0,
      activeInput: '',
      errors: {
        error: false,
        errorNombre: false,
        errorCuil: false,
        errorEmail: false,
        errorContrasena: false,
        errorCalle: false,
        errorNumero: false,
        errorProvincia: false,
        errorLocalidad: false
    },
      values: {...this.props.initialValues}
    };
  
      _onChangeValue = (name, value) =&gt; {
          this.setState(prevState =&gt; {
            return {
              values: {
                ...prevState.values,
                [name]: value
              }
            }, this.validate(name)
          })
        };
  </code></pre>
  
  <p>And this is the Validate Function, is a switch, so i much longer but the problem maybe could be that every case has another setState inside...</p>
  
  <pre><code>validate = input =&gt; {
  
      switch(input){
        case 'nombre':
          let { nombre } = this.state.values
          let splitNombre = nombre.split(' ');
  
          if ( splitNombre.length &gt; 1 &amp;&amp; splitNombre[1].length === 0 || nombre.length === 0 || splitNombre.length === 1 ) {
            this.setState(prevState =&gt; ({
              errors: { ...prevState.errors, error: true, errorNombre: true }
            }));
          } else {
            this.setState(prevState =&gt; ({
              errors: { ...prevState.errors, error: false, errorNombre: false }
            }));
          }
          break
  </code></pre>
  
  <p>As this is a compound component is a little messy but here is the files</p>
  
  <p>Input.js</p>
  
  <pre><code>import React, { PureComponent } from 'react';
  
  class Input extends PureComponent {
    _onChangeText = text =&gt; {
      this.props.onChangeValue(this.props.name, text);
    };
  
    render() {
      const { onChangeValue, name, ...rest } = this.props;
      return (
        &lt;input {...rest} onChange={(event) =&gt; this._onChangeText(event.target.value)} /&gt;
      );
    }
  }
  
  export default Input;
  </code></pre>
  
  <p>Steps.js</p>
  
  <pre><code>import Botones from './Botones'
  
      export default class Step extends PureComponent {
          state = {}
          render() {
            return (
              &lt;Fragment&gt;
  
                {this.props.children({
                  onChangeValue: this.props.onChangeValue,
                  values: this.props.values,
                  index: this.props.index,
                  errors: this.props.errors
                })}
  
                &lt;div&gt;
              &lt;Botones currentIndex={this.props.currentIndex}
                       prevStep={this.props.prevStep}
                       nextStep={this.props.nextStep}
                       onSubmit={this.props.onSubmit}
                       isLast={this.props.isLast}
                       isFirst={this.props.isFirst}
                       error={this.props.errors.error}    
              /&gt;
  
            &lt;/div&gt;
          &lt;/Fragment&gt;
        )
      }
    }
  </code></pre>
  
  <p>FirstStep.js</p>
  
  <pre><code>import Steps from './Steps';
  
  export default class FirstStep extends Component {
  
      constructor(props){
          super(props)
          this.state = {}
      }
  
      render() {
          //console.log(this.props)
          return (
              &lt;Fragment&gt;
                  &lt;Steps level={this.props.index}/&gt;
                  &lt;form onSubmit={this.onSubmit} className="mt90"&gt;
                      &lt;div&gt;
                          &lt;label&gt;Nombre completo&lt;/label&gt;
                          &lt;input type="text"
                                 name="nombre"
                                 placeholder="Escriba su nombre"
                                 onChange={ event =&gt; this.props.onChangeText('nombre', event.target.value) }
                                 value={this.props.values.nombre}
                                 className={ `${ this.props.errors.errorNombre &amp;&amp; "error-focus" }` }
                                 /&gt;
                          { this.props.errors.errorNombre &amp;&amp;
                          &lt;span className="error"&gt;No es un nombre completo&lt;/span&gt; }
                      &lt;/div&gt;
                      &lt;div className="mt50"&gt;
                          &lt;label&gt;N° de CUIL&lt;/label&gt;
                          &lt;input type="text"
                                 name="cuil"
                                 placeholder="Ej.: 23-45678901-2"
                                 onChange={ event =&gt; this.props.onChangeText('cuil', event.target.value) }
                                 value={this.props.values.cuil}
                                 className={ `${ this.props.errors.errorCuil &amp;&amp; "error-focus" }` }
                                 /&gt;
                          { this.props.errors.errorCuil &amp;&amp;
                          &lt;span className="error"&gt;No es un CUIL válido&lt;/span&gt; }
                      &lt;/div&gt;
                  &lt;/form&gt;
              &lt;/Fragment&gt;
          )
      }
  }
  </code></pre>
  
  <p>App.js (has the FirstStep as a child component)</p>
  
  <pre><code>[...]
  Render()
  &lt;RegisterBox.Step&gt;
              { ({ values, onChangeValue, index, errors }) =&gt; (
                &lt;FirstStep values={values} onChangeText={onChangeValue} index={index} errors={errors} /&gt;
              )}
            &lt;/RegisterBox.Step&gt;
  [...]
  </code></pre>